~ubuntu-branches/ubuntu/lucid/mew-beta/lucid

1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1
;;; mew-encode.el --- MIME syntax encoder for Mew
2
3
;; Author:  Kazu Yamamoto <Kazu@Mew.org>
4
;; Created: Oct  2, 1996
5
6
;;; Code:
7
8
(require 'mew)
9
10
(defvar mew-prog-mime-encode-switch
11
  `((,mew-b64 "-b")
12
    (,mew-qp  "-q")
13
    (,mew-xg  "-g")))
14
15
(defvar mew-prog-mime-encode-text-switch
16
  `((,mew-b64 "-b" "-t")
17
    (,mew-qp  "-q")
18
    (,mew-xg  "-g""-t")))
19
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
20
(defun mew-prog-mime-encode-get-opt (cte switch)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
21
  (cdr (mew-assoc-case-equal cte switch 0)))
22
23
(defvar mew-encode-multipart-encrypted-switch
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
24
  `((,mew-ct-pge mew-pgp-encrypt)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
25
26
(defvar mew-encode-multipart-signed-switch
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
27
  `((,mew-ct-pgs mew-pgp-sign mew-pgp-canonicalize)
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
28
    (,mew-ct-sms mew-smime-detach-sign)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
29
30
;;
31
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
32
(defun mew-encode-get-security-func (proto switch)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
33
  (nth 1 (mew-assoc-case-equal proto switch 0)))
34
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
35
(defun mew-encode-get-canonicalize-func (proto switch)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
36
  (nth 2 (mew-assoc-case-equal proto switch 0)))
37
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
38
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
;;;
40
;;; MIME encoder
41
;;;
42
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
43
(defun mew-encode-error (error-msg)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
44
  (mew-tinfo-set-encode-err error-msg)
45
  (error ""))
46
47
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48
;;;
49
;;; RFC 2822 comments
50
;;;
51
52
;; RFC 2822 defines the limitations of the number of fields.
53
;;
54
;; * Overriding
55
;;    Date: (exactly once)
56
;;    Message-Id:
57
;;
58
;; * Put multiple fields to a single field
59
;;    From: (exactly once)
60
;;    Reply-To:
61
;;    To:
62
;;    Cc:
63
;;
64
;; * Error and undo
65
;;    Sender: (if exist, exactly one address)
66
;;
67
;;    In-Reply-To:
68
;;    References:
69
;;    Subject:
70
;;
71
72
(defconst mew-multiple-field-error-list
73
  (list mew-subj: mew-in-reply-to: mew-references:))
74
75
(defconst mew-multiple-field-combine-list
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
76
  (list mew-from: mew-reply-to: mew-to: mew-cc:))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
77
78
(defun mew-header-count-field (field)
79
  (let ((case-fold-search t)
80
	(regex (format "^%s" field))
81
	(i 0))
82
    (goto-char (point-min))
83
    (while (re-search-forward regex nil t)
84
      (setq i (1+ i))
85
      (forward-line))
86
    i))
87
88
(defun mew-header-combine-field (field)
89
  (let ((case-fold-search t)
90
	(regex (format "^%s" field))
91
	beg med here value)
92
    (goto-char (point-min))
93
    (when (re-search-forward regex nil t)
94
      (forward-line)
95
      (mew-header-goto-next)
96
      (setq here (1- (point)))
97
      (while (re-search-forward regex nil t)
98
	(setq beg (match-beginning 0))
99
	(setq med (match-end 0))
100
	(forward-line)
101
	(mew-header-goto-next)
102
	(setq value (mew-buffer-substring med (1- (point))))
103
	(delete-region beg (point))
104
	(save-excursion
105
	  (goto-char here)
106
	  (insert ",\n\t" value)
107
	  (setq here (point)))))))
108
109
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
110
;;;
111
;;; Header sanity check
112
;;;
113
114
(defun mew-encode-remove-invalid-fields ()
115
  (when (mew-header-end)
116
    (save-excursion
117
      (save-restriction
118
	(narrow-to-region (point-min) (mew-header-end))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
119
	(dolist (field mew-multiple-field-error-list)
120
	  (if (> (mew-header-count-field field) 1)
121
	      (mew-encode-error (format "Multiple %s!" field))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
122
	(mapcar 'mew-header-combine-field mew-multiple-field-combine-list)))))
123
124
(defun mew-encode-ask-subject ()
125
  (when (and mew-ask-subject (not (mew-header-existp mew-subj:)))
126
    ;; Subject: does not exist
127
    (let ((subj (read-string (concat mew-subj: " "))))
128
      (mew-header-replace-value mew-subj: subj))))
129
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
130
(defun mew-encode-fcc-folder-check (fld)
131
  (let ((folder (mew-canonicalize-folder fld)))
132
    (when (and mew-ask-fcc
133
	       (mew-folder-localp folder)
134
	       (not (file-directory-p (mew-expand-folder folder))))
135
      (if (y-or-n-p (format "%s does not exist. Create it? " folder))
136
	  (mew-local-folder-check folder)
137
	(mew-encode-error "Edit Fcc:")))
138
    folder))
139
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
140
(defun mew-encode-ask-fcc (resentp)
141
  (let* ((target (if resentp mew-resent-fcc: mew-fcc:))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
142
	 (folders (mew-header-get-value target)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
143
    (when folders
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
144
      (mapcar
145
       'mew-encode-fcc-folder-check
146
       (mew-addrstr-parse-value-list2 folders)))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
147
148
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
149
;;;
150
;;; To:, Cc:
151
;;;
152
153
(defvar mew-draft-append-domain-p t)
154
155
(defun mew-draft-append-domain (addr)
156
  (if (string-match "@" addr)
157
      addr
158
    (if mew-draft-append-domain-p
159
	(concat addr "@" (mew-mail-domain (mew-tinfo-get-case)))
160
      (throw 'jump addr))))
161
162
(defun mew-encode-canonicalize-address (resentp)
163
  (catch 'jump
164
    (let ((case-fold-search t)
165
	  (regex (mew-make-field-regex
166
		  (if resentp mew-resent-dest:-list mew-destination:-list)))
167
	  key start vals val addrs addr ret insl ins prefix suffix)
168
      (save-excursion
169
	(save-restriction
170
	  (narrow-to-region (point-min) (mew-header-end))
171
	  (goto-char (point-min))
172
	  (while (re-search-forward regex nil t)
173
	    (setq key (match-string 1))
174
	    (setq start (match-end 0))
175
	    (forward-line)
176
	    (while (looking-at mew-lwsp)
177
	      (delete-backward-char 1)
178
	      (forward-line))
179
	    (setq val (mew-buffer-substring start (1- (point))))
180
	    (delete-region start (1- (point)))
181
	    (backward-char 1)
1.1.3 by Tatsuya Kinoshita
Import upstream version 5.0.53+5.1rc1
182
	    ;; single quote is allowed for local-part
183
	    (setq vals (mapcar 'mew-chop (mew-split-quoted val ?, ?: ?\; 'no-single)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
184
	    (dolist (val vals)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
185
	      (setq ins nil addrs nil)
186
	      (cond
187
	       ;; phrase:addr1,addr2;
188
	       ((string-match "[^:]+:[^;]+;" val)
189
		(let ((mew-alias-expand-prefix nil))
190
		  (setq addrs (mew-alias-expand val mew-addrbook-alist 0))
191
		  (setq addrs (mapcar 'mew-draft-append-domain addrs))
192
		  (setq ins (list (concat mew-alias-expand-prefix ":;")))))
193
	       ;; Name <addr>
194
	       ((and (setq addr (mew-addrstr-parse-address val))
195
		     (string-match (concat "\\(.*<\\)" (regexp-quote addr) "\\(>.*\\)")
196
				   val))
197
		(setq prefix (match-string 1 val))
198
		(setq suffix (match-string 2 val))
199
		(setq addr (mew-draft-append-domain addr))
200
		(setq addrs (list addr))
201
		(setq ins (list (concat prefix addr suffix))))
202
	       ;; addr
203
	       (t
204
		(let ((mew-alias-expand-prefix nil))
205
		  (setq addrs (mew-alias-expand val mew-addrbook-alist 0))
206
		  (setq addrs (mapcar 'mew-draft-append-domain addrs))
207
		  (if mew-alias-expand-prefix
208
		      (setq ins (list (concat mew-alias-expand-prefix ":;")))
209
		    (setq ins (copy-sequence addrs))))))
210
	      (setq insl (nconc insl ins))
211
	      (unless (string-match "bcc" key) ;; Removing Bcc:
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
212
		(setq ret (nconc ret addrs)))) ;; end of dolist
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
213
	    (insert " " (mapconcat 'identity insl ", "))
214
	    (setq insl nil)
215
	    (forward-line))))
216
      ret)))
217
	
218
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
219
;;;
220
;;; Dcc:, Bcc:
221
;;;
222
223
(defun mew-encode-delete-dcc (resentp)
224
  (let* ((target (list (if resentp mew-resent-dcc: mew-dcc:)))
225
	 (dcc (mew-header-parse-address-list target)))
226
    ;; Dcc: is already contained in recipients.
227
    ;; So, just delete it.
228
    ;; Delete {Resent-,}Dcc: anyway.
229
    (mew-header-delete-lines (list mew-dcc: mew-resent-dcc:))
230
    dcc))
231
232
(defun mew-encode-delete-bcc (resentp)
233
  (let* ((target (list (if resentp mew-resent-bcc: mew-bcc:)))
234
	 (bcc (mew-header-parse-address-list target)))
235
    (mew-header-delete-lines (list mew-bcc: mew-resent-bcc:)) ;; anyway
236
    bcc))
237
238
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
239
;;;
240
;;; Message-Id:, Date:
241
;;;
242
243
(defun mew-encode-id-date (pnm msgid &optional resentp)
244
  (let ((time (current-time)))
245
    (cond
246
     (resentp
247
      (mew-header-delete-lines (list mew-resent-date: mew-resent-message-id:))
248
      (save-excursion
249
	(goto-char (point-min))
250
	(mew-header-insert mew-resent-date: (mew-time-ctz-to-rfc time))
251
	(mew-header-insert mew-resent-message-id: msgid)))
252
     (t
253
      (mew-header-delete-lines (list mew-date: mew-message-id:))
254
      (save-excursion
255
	(goto-char (point-min))
256
	(mew-header-insert mew-date: (mew-time-ctz-to-rfc time))
257
	(mew-header-insert mew-message-id: msgid))))
258
    (list msgid (mew-time-ctz-to-logtime time))))
259
260
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
261
;;;
262
;;; From:, Sender:
263
;;;
264
265
(defun mew-encode-check-sender (resentp)
266
  (if (< 1 (length (mew-addrstr-parse-address-list
267
		    (mew-header-get-value
268
		     (if resentp mew-resent-sender: mew-sender:)))))
269
      (mew-encode-error "Sender: must contain one address!")))
270
271
(defun mew-encode-from (case resentp)
272
  (unless (mew-header-existp mew-from:)
273
    (let ((from (mew-from case)))
274
      (save-excursion
275
	(goto-char (point-min))
276
	(if resentp
277
	    (mew-header-insert mew-resent-from: from)
278
	  (mew-header-insert mew-from: from))))))
279
280
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
281
;;;
282
;;; Learning aliases
283
;;;
284
285
;; xxx Bcc: and/or Dcc:?
286
(defun mew-encode-learn-aliases (resentp)
287
  (if (and mew-use-auto-alias mew-addrbook-append-domain-p)
288
      ;; If mew-addrbook-append-domain-p is nil, automatic
289
      ;; short names would be conflicted to local users.
290
      (mapcar 'mew-addrbook-alias-add
291
	      (mew-header-parse-address-list
292
	       (if resentp
293
		   (list mew-resent-to: mew-resent-cc:)
294
		 (list mew-to: mew-cc:))))))
295
296
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
297
;;;
298
;;; Misc
299
;;;
300
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
301
(defun mew-encode-set-privacy (pnm privacy case)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
302
  (unless (or (mew-syntax-get-privacy mew-encode-syntax) ;; specified
303
	      ;; encryption previously failed, so bypass.
304
	      (and (null privacy) (mew-tinfo-get-privacy-err)))
305
    (let (type)
306
      (cond
307
       (privacy
308
	(setq type privacy))
309
       ((mew-tinfo-get-privacy-type)
310
	(setq type (mew-tinfo-get-privacy-type)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
311
       ((and (mew-tinfo-get-encrypted-p) (mew-protect-privacy-encrypted case))
312
	(setq type (mew-protect-privacy-encrypted-type case)))
313
       ((mew-protect-privacy-always case)
314
	(setq type (mew-protect-privacy-always-type case))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
315
      (mew-syntax-set-privacy
316
       mew-encode-syntax
317
       (mew-pcdb-ct (mew-pcdb-by-service type)))
318
      ;; recipients are ignored when signing
319
      (mew-syntax-set-decrypters
320
       mew-encode-syntax (mew-smtp-get-recipients pnm)))))
321
322
(defun mew-encode-make-header (&optional addsep resentp)
323
  (unless (mew-header-existp mew-mv:)
324
    (goto-char (mew-header-end))
325
    (mew-header-insert mew-mv: mew-mv:-num))
326
  (mew-header-encode-region (point-min) (mew-header-end) resentp)
327
  (cond
328
   (addsep ;; reedit
329
    ;; To:
330
    ;; Content-*
331
    ;; ----
332
    (mew-header-clear) ;; mew-in-header-p() returns nil
333
    ;; To:
334
    ;; Content-*
335
    (insert "\n"))
336
   (t
337
    ;; To:
338
    ;; ----
339
    ;; Content-*
340
    (mew-header-clear) ;; mew-in-header-p returns nil
341
    ;; To:
342
    ;; Content-*
343
    ))
344
  (mew-header-goto-end)
345
  (mew-highlight-header-region (point-min) (point)))
346
347
(defun mew-encode-save-draft ()
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
348
  (mew-frwlet mew-cs-dummy mew-cs-text-for-write
349
    (write-region (point-min) (point-max) (buffer-file-name) nil 'no-msg)
350
    (clear-visited-file-modtime)
351
    (mew-delete-file buffer-auto-save-file-name)
352
    (set-buffer-modified-p nil)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
353
354
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
355
;;;
356
;;; Encoding a message
357
;;;
358
359
(defun mew-smtp-encode (pnm case resentp fcc &optional privacy signer headerp)
360
  (let ((ret t))
361
    (if (mew-debug 'encode)
362
	(let ((debug-on-error t))
363
	  (mew-smtp-encode-message pnm case resentp fcc privacy signer headerp))
364
      (condition-case nil
365
	  (mew-smtp-encode-message pnm case resentp fcc privacy signer headerp)
366
	(error
367
	 (mew-encode-undo)
368
	 (message "%s" (mew-tinfo-get-encode-err))
1.1.2 by Tatsuya Kinoshita
Import upstream version 5.0.53
369
	 (setq ret nil))
370
	(quit
371
	 (mew-encode-undo)
372
	 (message "quit")
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
373
	 (setq ret nil))))
374
    ret))
375
376
(defun mew-smtp-encode-message (pnm case resentp fcc &optional privacy signer headerp)
377
  (mew-set-buffer-multibyte t)
378
  (if (buffer-modified-p) (save-buffer)) ;; to make backup
379
  (widen)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
380
  (let (multip recipients msgid logtime)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
381
    (mew-smtp-set-raw-header
382
     pnm (mew-buffer-substring (point-min) (mew-header-end)))
383
    (unless headerp
384
      ;; Let's backup
385
      (if (mew-attach-p)
386
	  (progn
387
	    (setq multip t)
388
	    (mew-attach-clear))
389
	(unless mew-encode-syntax
390
	  (setq mew-encode-syntax
391
		(mew-encode-syntax-single "text.txt" (list mew-ct-txt)))))
392
      (mew-encode-make-backup))
393
    ;; Errors can be caused from here.
394
    (goto-char (point-min))
395
    (mew-encode-remove-invalid-fields)
396
    ;; Destination check
397
    (setq recipients (mew-encode-canonicalize-address resentp))
398
    ;; Bcc: is not included.
399
    (mew-smtp-set-recipients pnm recipients)
400
    (mew-smtp-set-orig-recipients pnm recipients)
401
    (cond
402
     ((null recipients)
403
      (mew-encode-error "No recipient!"))
404
     ((stringp recipients)
405
      (mew-encode-error (format "'%s' is not in the right form!" recipients))))
406
    ;; Header modifications which are not remained.
407
    (mew-header-delete-lines (list mew-fcc: mew-resent-fcc:)) ;; anyway
1.1.2 by Tatsuya Kinoshita
Import upstream version 5.0.53
408
    (mew-encode-delete-dcc resentp)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
409
    (mew-smtp-set-bcc pnm (mew-encode-delete-bcc resentp))
410
    (mew-smtp-set-fcc pnm fcc)
411
    ;;
412
    (mew-encode-check-sender resentp)
413
    (mew-encode-from case resentp)
414
    ;;
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
415
    (mew-set '(msgid logtime) (mew-encode-id-date pnm (mew-smtp-message-id case) resentp))
416
    (mew-smtp-set-msgid pnm msgid)
417
    (mew-smtp-set-logtime pnm logtime)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
418
    ;;
419
    (goto-char (mew-header-end))
420
    (forward-line) ;; necessary for PGP
421
    ;;
422
    (message "Making a message...")
423
    ;; save syntax before setting privacy
424
    (unless headerp
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
425
      (mew-encode-set-privacy pnm privacy case)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
426
      (let (mew-inherit-encode-pgp-signer
427
	    mew-inherit-encode-smime-signer)
428
	(setq mew-inherit-encode-pgp-signer
429
	      (or signer
430
		  (mew-pgp-signer (mew-tinfo-get-case))
431
		  (mew-get-my-address)))
432
	(setq mew-inherit-encode-smime-signer
433
	      (or signer
434
		  (mew-smime-signer (mew-tinfo-get-case))
435
		  (mew-get-my-address)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
436
	(goto-char (mew-header-end)) ;; due to invalid null lines in the header
437
	(forward-line)
438
	(if multip
439
	    (mew-encode-make-multi)
440
	  (mew-encode-make-single))))
441
    (mew-encode-make-header headerp resentp)
442
    ;; Learn aliases after no error occurred
443
    (mew-encode-learn-aliases resentp)
444
    (mew-encode-save-draft)
445
    (mew-overlay-delete-buffer)
446
    (message "Making a message...done")))
447
448
(defun mew-nntp2-encode (pnm case fcc &optional privacy signer headerp)
449
  (let ((ret t))
450
    (if (mew-debug 'encode)
451
	(let ((debug-on-error t))
452
	  (mew-nntp2-encode-message pnm case fcc privacy signer headerp))
453
      (condition-case nil
454
	  (mew-nntp2-encode-message pnm case fcc privacy signer headerp)
455
	(error
456
	 (mew-encode-undo)
457
	 (message "%s" (mew-tinfo-get-encode-err))
1.1.2 by Tatsuya Kinoshita
Import upstream version 5.0.53
458
	 (setq ret nil))
459
	(quit
460
	 (mew-encode-undo)
461
	 (message "quit")
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
462
	 (setq ret nil))))
463
    ret))
464
465
(defun mew-nntp2-encode-message (pnm case fcc &optional privacy signer headerp)
466
  (mew-set-buffer-multibyte t)
467
  (if (buffer-modified-p) (save-buffer)) ;; to make backup
468
  (widen)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
469
  (let (multip newsgroups msgid logtime)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
470
    (mew-nntp2-set-raw-header
471
     pnm (mew-buffer-substring (point-min) (mew-header-end)))
472
    ;; Let's backup
473
    (unless headerp
474
      (if (mew-attach-p)
475
	  (progn
476
	    (setq multip t)
477
	    (mew-attach-clear))
478
	(setq mew-encode-syntax
479
	      (mew-encode-syntax-single "text.txt" (list mew-ct-txt))))
480
      (mew-encode-make-backup))
481
    ;; Errors can be caused from here.
482
    (goto-char (point-min))
483
    (mew-encode-remove-invalid-fields)
484
    ;; Newsgroups check
485
    (setq newsgroups (mew-header-get-value mew-newsgroups:))
486
    (mew-nntp2-set-newsgroups pnm newsgroups)
487
    (unless newsgroups (mew-encode-error "No newsgroups!"))
488
    ;; Header modifications which are not remained.
489
    (mew-header-delete-lines (list mew-fcc: mew-resent-fcc:)) ;; anyway
490
    (mew-nntp2-set-fcc pnm fcc)
491
    ;;
492
    (mew-encode-from case nil)
493
    ;;
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
494
    (mew-set '(msgid logtime) (mew-encode-id-date pnm (mew-nntp-message-id case)))
495
    (mew-nntp2-set-msgid pnm msgid)
496
    (mew-nntp2-set-logtime pnm logtime)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
497
    ;;
498
    (goto-char (mew-header-end))
499
    (forward-line) ;; necessary for PGP
500
    ;;
501
    (message "Making a message...")
502
    ;; save syntax before setting privacy
503
    (unless headerp
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
504
      (mew-encode-set-privacy pnm privacy case)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
505
      (let (mew-inherit-encode-pgp-signer
506
	    mew-inherit-encode-smime-signer)
507
	(setq mew-inherit-encode-pgp-signer
508
	      (or signer
509
		  (mew-pgp-signer (mew-tinfo-get-case))
510
		  (mew-get-my-address)))
511
	(setq mew-inherit-encode-smime-signer
512
	      (or signer
513
		  (mew-smime-signer (mew-tinfo-get-case))
514
		  (mew-get-my-address)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
515
	(goto-char (mew-header-end)) ;; due to invalid null lines in the header
516
	(forward-line)
517
	(if multip
518
	    (mew-encode-make-multi)
519
	  (mew-encode-make-single))))
520
    (mew-encode-make-header nil)
521
    (mew-encode-save-draft)
522
    (mew-overlay-delete-buffer)
523
    (message "Making a message...done")))
524
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
525
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
526
;;;
527
;;; Encoding singlepart
528
;;;
529
530
(defun mew-encode-make-single ()
531
  ;; Just after the header
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
532
  ;; Using Multipart/Signed if the body is a single part.
533
  (if (equal (mew-syntax-get-privacy mew-encode-syntax)
534
	     `((,mew-ct-smm ,mew-ct-smm-sig)))
535
      (mew-syntax-set-privacy mew-encode-syntax `((,mew-ct-mls ,mew-ct-sms))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
536
  (mew-encode-singlepart mew-encode-syntax nil nil t 'cover))
537
538
(defun mew-encode-charset-8bitp (charset)
539
  (let ((case-fold-search t))
540
    (if (or (mew-case-equal mew-us-ascii charset)
541
	    (string-match "^iso-2022" charset))
542
	nil
543
      t)))
544
545
(defun mew-encode-file-8bitp (file)
546
  (if (and (mew-which-exec mew-prog-8bit) (file-readable-p file))
547
      (eq (call-process mew-prog-8bit file nil nil "-8") 1)))
548
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
549
(defun mew-encode-limit-7bitp (privacy)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
550
  ;; Only parts to be signed FIRST are limited to 7bit.
551
  (and privacy (mew-case-equal mew-ct-mls (car (car privacy)))))
552
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
553
(defvar mew-encode-max-line-length 990)
554
;; RFC 2822 defines 1000 but Sendmail uses 990
555
556
(defvar mew-ask-encoding t)
557
(defvar mew-default-encoding mew-b64)
558
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
559
(defun mew-encode-mime-body (ctl cte file no-encoding)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
560
  ;; If file is 't', target is buffered.
561
  ;; text should be buffered
562
  ;; 	- specified charset is a rare case
563
  ;; 	- copy overhead may be small
564
  (let* ((ct (mew-syntax-get-value ctl 'cap))
565
         (textp (mew-ct-textp ct))
566
	 (charset (if textp (mew-syntax-get-param ctl "charset")))
567
	 (icharset (if textp (mew-syntax-get-param ctl "icharset")))
568
         (linebasep (or textp (mew-ct-linebasep ct)))
569
         (switch (if linebasep
570
                     mew-prog-mime-encode-text-switch
571
                   mew-prog-mime-encode-switch))
572
         (beg (point))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
573
	 buffer cs opt last flowed delsp flowed-delsp)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
574
    (if (and (stringp file)
575
	     (setq buffer (get-file-buffer file))
576
	     (buffer-modified-p buffer))
1.2.5 by Tatsuya Kinoshita
Import upstream version 7.0.50~0.20100105
577
	(with-current-buffer buffer
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
578
	  (save-buffer)))
579
    (when textp
580
      (when (and (stringp file) (file-readable-p file))
581
	(when icharset
582
	  (setq cs (mew-charset-to-cs icharset))
583
	  (unless (mew-coding-system-p cs)
584
	    (mew-encode-error
585
	     (format "Unknown coding system %s in the body"
586
		     (symbol-name cs)))))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
587
	(mew-frwlet (or cs mew-cs-autoconv) mew-cs-dummy
588
	  (mew-insert-file-contents file)))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
589
      ;; A user may specify charset to convey JIS X 0201 Katakana.
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
590
      ;; So, we need to avoid the sanity check.
591
      (unless charset
592
	(if mew-use-charset-sanity-check
593
	    (mew-charset-sanity-check beg (point-max)))
594
	(setq charset (mew-charset-guess-region beg (point-max))))
595
      (setq cs (mew-charset-to-cs charset))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
596
      (when (string= mew-ct-txt ct)
597
	(cond
598
	 ((mew-tinfo-get-flowed)
599
	  (setq flowed t)
600
	  (if (string= (mew-tinfo-get-flowed) "yes")
601
	      (setq delsp t)))
602
	 ((mew-tinfo-get-use-flowed)
603
	  (setq flowed-delsp (mew-encode-flowed beg (point-max) charset))
604
	  (mew-set '(flowed delsp) flowed-delsp))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
605
      (unless (mew-coding-system-p cs)
606
	(mew-encode-error
607
	 (format "Unknown coding system %s in the body" (symbol-name cs))))
608
      (mew-cs-encode-region beg (point-max) cs))
609
    ;; decide cte
610
    (cond
611
     (textp
612
      (cond
613
       ((and cte (or (mew-case-equal cte mew-b64) (mew-case-equal cte mew-qp)))
614
	;; user specified and in 7bit domain, so do nothing.
615
	)
616
       (t
617
	(if (or (null cte) (mew-case-equal cte mew-bin))
618
	    ;; retain the user-specified cte
619
	    (setq cte (mew-charset-to-cte charset)))
620
	(if (or (null cte) (mew-case-equal cte mew-bin))
621
	    ;; unknown charset
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
622
	    (setq cte mew-default-encoding))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
623
	(cond
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
624
	 (no-encoding
625
	  (if (mew-encode-charset-8bitp charset)
626
	      (setq cte mew-8bit)
627
	    (setq cte mew-7bit)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
628
	 (mew-inherit-7bit
629
	  (if (mew-case-equal cte mew-8bit)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
630
	      (setq cte mew-default-encoding)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
631
	 (mew-use-8bit
632
	  (if (mew-encode-charset-8bitp charset)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
633
	      (setq cte mew-8bit))))
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
634
	(when (and (not no-encoding)
635
		   (or (mew-case-equal cte mew-7bit)
636
		       (mew-case-equal cte mew-8bit)))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
637
	  (save-excursion
638
	    (goto-char beg)
639
	    (mew-set-buffer-multibyte nil)
640
	    (catch 'long-line
641
	      (while t
642
		(setq last (point))
643
		(if (/= (forward-line) 0) (end-of-line))
644
		(when (>= (- (point) last) mew-encode-max-line-length) ;; including LF
645
		  (if (not mew-ask-encoding)
646
		      (setq cte mew-default-encoding)
647
		    (setq cte (mew-input-encoding)))
648
		  (throw 'long-line nil))
649
		(if (eobp) (throw 'long-line nil))))
650
	    (mew-set-buffer-multibyte t))))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
651
     ((string= ct mew-ct-msg)
652
      (if (mew-encode-file-8bitp file)
653
	  (setq cte mew-8bit)
654
	(setq cte mew-7bit)))
655
     (t
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
656
      (if (and no-encoding cte (mew-case-equal cte mew-b64))
657
	  (setq cte mew-bin))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
658
      ;; There are 7bit ascii bodies such as
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
659
      ;; application/pgp-encrypted and message/external-body.
660
      ;; If 7bit or 8bit, it should be linebase.
661
      (if (null cte) (setq cte mew-7bit))))
662
    (cond
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
663
     ((mew-case-equal cte mew-bin)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
664
      (mew-frwlet mew-cs-binary mew-cs-dummy
665
	(mew-insert-file-contents file)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
666
     ((or (mew-case-equal cte mew-7bit) (mew-case-equal cte mew-8bit))
667
      ;; Certainly linebase here.
668
      (unless textp
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
669
	(mew-frwlet mew-cs-text-for-read mew-cs-dummy
670
	  (mew-insert-file-contents file)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
671
      (when (and (string= ct mew-ct-msg)
672
		 (or mew-inherit-7bit (not mew-use-8bit))
673
		 (mew-case-equal cte mew-8bit))
674
	(save-restriction
675
	  (setq cte mew-7bit)
676
	  (narrow-to-region beg (point-max))
677
	  (mew-convert-message))))
678
     ((and (mew-case-equal cte mew-b64) (fboundp 'base64-encode-region))
679
      (unless textp
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
680
	(mew-frwlet (if linebasep mew-cs-text-for-read mew-cs-binary) mew-cs-dummy
681
	  (mew-insert-file-contents file)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
682
      (when linebasep
683
	(goto-char beg)
684
	(mew-lf-to-crlf))
685
      (base64-encode-region beg (point-max))
686
      (goto-char (point-max))
687
      (insert "\n"))
688
     ((mew-which-exec mew-prog-mime-encode)
689
      (setq opt (mew-prog-mime-encode-get-opt cte switch))
690
      (if (null opt)
691
	  (mew-encode-error (concat "Unknown CTE: " cte))
692
	(when textp
693
	  (setq file (mew-make-temp-name))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
694
	  (mew-frwlet mew-cs-dummy mew-cs-text-for-write
695
	    ;; NEVER use call-process-region for privacy reasons
696
	    (write-region beg (point-max) file nil 'no-msg))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
697
	  (delete-region beg (point-max)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
698
	(mew-piolet mew-cs-text-for-read mew-cs-dummy
699
	  (apply 'call-process mew-prog-mime-encode file t nil opt))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
700
	(if textp (mew-delete-file file))))
701
     (t
702
      (mew-encode-error (concat mew-prog-mime-encode " does not exist"))))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
703
    (list cte charset flowed delsp)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
704
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
705
(defun mew-encode-no-mime-encoding (privacy)
706
  (let ((first (car privacy)))
707
    (and (listp first)
1.1.7 by Tatsuya Kinoshita
Import upstream version 5.2.50~0.20070423
708
	 (or (string= (car first) mew-ct-mle)
709
	     (string= (car first) mew-ct-smm)))))
1.2.2 by Tatsuya Kinoshita
Import upstream version 6.0.51
710
1.1.8 by Tatsuya Kinoshita
Import upstream version 5.2.50~0.20070620
711
(defun mew-broken-name (cdpl)
712
  (let ((mew-encode-word-max-length 1000) ;; xxx
713
	(file (nth 1 (assoc "filename" cdpl)))
714
	name)
715
    (when (and file (string-match mew-regex-nonascii file))
716
      (setq name (car (mew-header-encode-string file)))
717
      ;; name must not be double-quoted here.
718
      ;; mew-heaer-insert will do this later
719
      (list "name" name))))
720
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
721
(defun mew-encode-flowed (beg end charset)
722
  "Encoding lines with RFC 3676"
723
  (let (flowed delsp column)
724
    (save-excursion
725
      (goto-char beg)
726
      (save-restriction
727
	(narrow-to-region beg end)
728
	(when (mew-encode-flowed-check)
729
	  (setq flowed t)
730
	  (setq delsp (mew-charset-to-delsp charset))
731
	  (setq column mew-flowed-fold-length)
732
	  (if delsp (setq column (1- column)))
733
	  (while (not (eobp))
734
	    (mew-encode-flowed-line column delsp)
735
	    (forward-line)))))
736
    (list flowed delsp)))
737
738
(defun mew-encode-flowed-remove-trailing-sp ()
739
  (while (and (not (bobp)) (= (char-before) mew-sp))
740
    (delete-backward-char 1)))
741
742
(defun mew-encode-flowed-line (column delsp)
743
  (let (prefix beg)
744
    (looking-at "^>*")
745
    (setq prefix (mew-match-string 0))
746
    (goto-char (match-end 0))
747
    (if (looking-at " ")
748
	(if (string= prefix "")
749
	    (insert mew-flowed-stuffed)
750
	  (progn
751
	    (setq prefix (format "%s%c" prefix mew-flowed-stuffed))
752
	    (forward-char)))
753
      (when (looking-at "From ")
754
	(insert mew-flowed-stuffed)
755
	(setq prefix (format "%s%c" prefix mew-flowed-stuffed))))
756
    (setq beg (point))
757
    (save-excursion
758
      (end-of-line)
759
      (unless (and (= (- (point) beg) 3)
760
		   (string= (mew-buffer-substring beg (point)) "-- "))
761
	(mew-encode-flowed-remove-trailing-sp)))
762
    (move-to-column column)
763
    (catch 'loop
764
      (while (not (eolp))
765
	(cond
766
	 (delsp
767
	  (while (> (current-column) column)
768
	    (backward-char 1))
769
	  (insert " \n"))
770
	 (t
771
	  (if (search-backward " " beg t)
772
	      (forward-char)
773
	    (unless (search-forward " " (save-excursion (end-of-line) (point)) t)
774
	      (throw 'loop (end-of-line))))
775
	  (insert "\n")))
776
	(insert prefix)
777
	(setq beg (point))
778
	(move-to-column column)))))
779
780
(defun mew-encode-flowed-check ()
781
  (catch 'loop
782
    (save-excursion
783
      (save-restriction
784
	(narrow-to-region (point-min) (min (point-max) mew-file-max-size))
785
	(goto-char (point-min))
786
	(while (not (eobp))
787
	  (end-of-line)
788
	  (if (> (current-column) mew-flowed-fold-threshold)
789
	      (throw 'loop t))
790
	  (forward-line))))))
791
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
792
(defun mew-encode-singlepart (syntax &optional path depth buffered coverp)
793
  ;; path is nil if called make-single or security multipart
794
  ;; buffered is t if called make-single
795
  (run-hook-with-args 'mew-encode-singlepart-hook
796
                      syntax path depth buffered)
797
  (let* ((file (expand-file-name (mew-syntax-get-file syntax) path))
798
	 (ctl (mew-syntax-get-ct syntax))
799
         (ct (mew-syntax-get-value ctl 'cap))
800
	 (cte (mew-syntax-get-cte syntax))
801
	 (cd (mew-syntax-get-cd syntax))
802
	 (cdpl (mew-syntax-get-cdp syntax))
803
	 (privacy (mew-syntax-get-privacy syntax))
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
804
	 (no-encoding (mew-encode-no-mime-encoding privacy))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
805
	 (mew-inherit-7bit (mew-encode-limit-7bitp privacy))
806
	 (beg (point))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
807
	 mret charset bodybeg cst ask-cst broken-name flowed delsp)
808
    (setq mret (mew-encode-mime-body ctl cte (or buffered file) no-encoding))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
809
    (goto-char beg)
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
810
    (mew-set '(cte charset flowed delsp) mret)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
811
    (setq ctl (mew-delete "icharset" ctl))
812
    (when charset
813
      (setq ctl (mew-syntax-get-params ctl))
814
      (setq ctl (mew-delete "charset" ctl))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
815
      (setq ctl (cons ct (cons (list "charset" charset) ctl))))
816
    (when flowed
817
      (setq ctl (nconc ctl (list (list "format" "flowed"))))
818
      (if delsp (setq ctl (nconc ctl (list (list "delsp" "yes"))))))
1.1.8 by Tatsuya Kinoshita
Import upstream version 5.2.50~0.20070620
819
    ;;
820
    (setq ctl (mew-delete "name" ctl))
821
    (setq broken-name (mew-broken-name cdpl))
822
    (if broken-name (setq ctl (nconc ctl (list broken-name))))
823
    ;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
824
    (mew-header-insert mew-ct: ctl)
825
    (mew-header-insert mew-cte: cte)
826
    (and cd (mew-header-insert mew-cd: cd))
827
    (and cdpl (mew-header-insert mew-cdp: cdpl))
828
    (insert "\n")
829
    ;; header "\n" (cur) [text]
830
    (setq bodybeg (point))
831
    (goto-char (point-max))
832
    (when (and (string= ct mew-ct-msg) mew-field-delete-for-forwarding)
833
      (save-restriction
834
	(narrow-to-region bodybeg (point-max))
835
	(mew-header-delete-lines mew-field-delete-common)
836
	(mew-header-delete-lines mew-field-delete-for-forwarding)))
837
    (when privacy
838
      (mew-encode-security-multipart
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
839
       beg privacy depth (mew-syntax-get-decrypters syntax) cte))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
840
    (goto-char (point-max))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
841
    (when (and coverp (setq cst charset))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
842
      (cond
843
       ((null mew-ask-charset)
844
	;; not ask
845
	)
846
       ((eq mew-ask-charset t)
847
	(if (mew-member-case-equal cst mew-cs-m17n-list)
848
	    (setq ask-cst t)))
849
       ((listp mew-ask-charset)
850
	(unless (mew-member-case-equal cst mew-ask-charset)
851
	  (setq ask-cst t))))
852
      (if (and ask-cst
853
	       (not (y-or-n-p (format "%s is used. OK? " cst))))
854
	  (mew-encode-error "Modify body")))
855
    (mew-case-equal cte mew-8bit)))
856
857
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
858
;;;
859
;;; Encoding multipart
860
;;;
861
862
(defun mew-encode-make-multi ()
863
  ;; Just after the header
864
  (let (beg path multip buffered privacy decrypters first ct)
865
    (if (mew-encode-syntax-have-one-part)
866
	;; A user may want to do any MIME stuff to the body
867
	(progn
868
	  (setq mew-encode-syntax (mew-syntax-get-part mew-encode-syntax))
869
	  (setq buffered t))
870
      ;; See if a cover page is empty or not
871
      (setq beg (point))
872
      (save-excursion
873
	(while (and (looking-at "^$") (not (eobp)))
874
	  (forward-line))
875
	(unless (eobp)
876
	  ;; The cover page exists.
877
	  (setq buffered t)))
878
      (setq path (mew-expand-folder mew-attach-folder))
879
      (if buffered
880
	  ;; The cover page exists.
881
	  (setq multip t)
882
	;; The cover page does not exist.
883
	(delete-region beg (point-max))
884
	;; Remove the cover page entry from the syntax.
885
	(setq mew-encode-syntax
886
	      (mew-syntax-remove-entry mew-encode-syntax '(1)))
887
	;; After removing the over page, see if this message has
888
	;; only one text part.
889
	(if (not (mew-encode-syntax-have-one-part))
890
	    (setq multip t)
891
	  (setq first (mew-syntax-get-part mew-encode-syntax))
892
	  (setq ct (mew-syntax-get-value (mew-syntax-get-ct first) 'cap))
893
	  (if (not (mew-ct-textp ct))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
894
	      (setq multip t)		
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
895
	    (setq path (expand-file-name
896
			(mew-syntax-get-file mew-encode-syntax) path))
897
	    (setq privacy (mew-syntax-get-privacy mew-encode-syntax))
898
	    (setq decrypters (mew-syntax-get-decrypters mew-encode-syntax))
899
	    (setq mew-encode-syntax (mew-syntax-get-part mew-encode-syntax))
900
	    (mew-syntax-set-privacy mew-encode-syntax privacy)
901
	    (mew-syntax-set-decrypters mew-encode-syntax decrypters)))))
902
    (if multip
903
	(mew-encode-multipart mew-encode-syntax path 0 buffered)
904
      (mew-encode-singlepart mew-encode-syntax path nil nil 'cover))))
905
906
(defvar mew-default-boundary "--%s(%s_%s)--")
907
908
(defun mew-boundary-get (&optional string)
909
  ;; boundary is less than or equal to 70
910
  (unless string (setq string "Next_Part"))
911
  (format mew-default-boundary
912
	  string
913
	  (mew-replace-character
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
914
	   (mew-replace-character (current-time-string) mew-sp ?_) ?: ?_)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
915
	  (mew-random-string 3 t)))
916
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
917
(defun mew-encode-multipart (syntax path depth &optional buffered cte)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
918
  (let* ((boundary
919
	  (mew-boundary-get ;; 0 is nil for Next_Part
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
920
	   (if (> depth 0) (format "BOUNDARY%s" (number-to-string depth)))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
921
	 (fullname (expand-file-name (mew-syntax-get-file syntax) path))
922
	 (ctl (mew-syntax-get-ct syntax))
923
	 (ct (mew-syntax-get-value ctl 'cap))
924
	 (cd (mew-syntax-get-cd syntax))
925
	 (privacy (mew-syntax-get-privacy syntax))
926
	 (mew-inherit-7bit (mew-encode-limit-7bitp privacy))
927
	 (len (length syntax))
928
	 (beg (point))
929
	 (cnt mew-syntax-magic)
930
	 (8bit-cnt 0)
931
	 8bitp cte-pos cover)
932
    (mew-header-insert mew-ct: (list ct (list "boundary" boundary)))
933
    (setq cte-pos (point))
934
    (and cd (mew-header-insert mew-cd: cd))
935
    (while (< cnt len)
936
      (insert "\n--" boundary "\n")
937
      (if (mew-syntax-multipart-p (aref syntax cnt))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
938
	  (setq 8bitp (mew-encode-multipart
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
939
		       (aref syntax cnt)
940
		       fullname
941
		       (1+ depth)))
942
	(if (and (= depth 0) (= cnt mew-syntax-magic ))
943
	    (setq cover t)
944
	  (setq cover nil))
945
	(setq 8bitp (mew-encode-singlepart
946
		     (aref syntax cnt)
947
		     fullname
948
		     (1+ depth)
949
		     (if (eq cnt mew-syntax-magic) buffered nil)
950
		     cover)))
951
      (if 8bitp (setq 8bit-cnt (1+ 8bit-cnt)))
952
      (setq cnt (1+ cnt)))
953
    (insert "\n--" boundary "--\n")
954
    (save-excursion
955
      (goto-char cte-pos)
956
      (mew-header-insert mew-cte: (if (> 8bit-cnt 0) mew-8bit mew-7bit)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
957
    (when privacy
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
958
      (mew-encode-security-multipart
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
959
       beg privacy depth (mew-syntax-get-decrypters syntax) cte))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
960
    (goto-char (point-max))
961
    (> 8bit-cnt 0)))
962
963
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
964
;;;
965
;;; Privacy services
966
;;;
967
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
968
(defun mew-encode-security-multipart (beg privacy depth decrypters cte)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
969
  (save-restriction
970
    (narrow-to-region beg (point-max))
971
    (let (proto ct)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
972
      (dolist (ent privacy)
973
	(goto-char (point-min))
974
	(mew-set '(ct proto) ent)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
975
	(setq ct (mew-capitalize ct))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
976
	(cond
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
977
	 ((string= ct mew-ct-mle)
978
	  (mew-encode-multipart-encrypted ct proto depth decrypters cte))
979
	 ((string= ct mew-ct-mls)
980
	  (mew-encode-multipart-signed ct proto depth))
981
	 ((string= ct mew-ct-smm)
982
	  (mew-encode-smime proto cte decrypters)))))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
983
984
(defun mew-security-multipart-boundary (depth)
985
   (if depth
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
986
       (mew-boundary-get (format "Security_Multipart%s" (number-to-string depth)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
987
     (mew-boundary-get "Security_Multipart")))
988
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
989
(defun mew-save-transfer-form (beg end retain &optional cte)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
990
  ;; called in the narrowed region
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
991
  (let ((sbeg beg) (send end) (draft-buf (current-buffer))
992
	(ocs mew-cs-text-for-net)
993
	tmpbuf file)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
994
    (if retain
995
	(progn
996
	  (setq tmpbuf (generate-new-buffer mew-buffer-prefix))
997
	  (set-buffer tmpbuf)
998
	  (mew-erase-buffer)
999
	  (mew-insert-buffer-substring draft-buf beg end)
1000
	  (setq sbeg (point-min) send (point-max))))
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
1001
    (goto-char sbeg) ;; just in case
1002
    (if (and cte (mew-case-equal cte mew-bin)
1003
	     (re-search-forward mew-eoh))
1004
	(progn
1005
	  (setq ocs mew-cs-binary)
1006
	  (forward-line)
1007
	  (save-restriction
1008
	    (narrow-to-region sbeg (point))
1009
	    (goto-char sbeg)
1010
	    (mew-lf-to-crlf)))
1011
      (unless mew-cs-text-for-net
1012
	(goto-char sbeg) ;; just in case
1013
	(mew-lf-to-crlf)))
1014
    (setq send (point-max))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1015
    (setq file (mew-make-temp-name))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1016
    (mew-frwlet mew-cs-dummy ocs
1017
      (write-region sbeg send file nil 'no-msg))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1018
    (if retain
1019
	(mew-remove-buffer tmpbuf)
1020
      (delete-region sbeg send))
1021
    (set-buffer draft-buf)
1022
    file)) ;; return value
1023
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
1024
(defun mew-encode-multipart-encrypted (ct proto depth decrypters cte)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1025
  ;; called in the narrowed region
1026
  (let* ((boundary (mew-security-multipart-boundary depth))
1027
	 (switch mew-encode-multipart-encrypted-switch) ;; save length
1028
	 (func (mew-encode-get-security-func proto switch))
1029
	 file1 file2 file3 cte2 cte3 fc errmsg)
1030
    ;; Write the part converting line breaks.
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
1031
    (setq file1 (mew-save-transfer-form (point-min) (point-max) nil cte))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1032
    ;; The narrowed region stores nothing
1033
    ;; Call the protocol function
1034
    (condition-case nil
1035
	(setq fc (funcall func file1 decrypters))
1036
      (error
1037
       (mew-delete-file file1)
1038
       (mew-encode-error
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1039
	(format "unknown error for %s. Check %s, anyway"
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1040
		mew-ct-mle mew-temp-dir))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1041
    (mew-set '(file2 cte2 file3 cte3 errmsg) fc)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1042
    (if errmsg
1043
	(progn
1044
	  (mew-delete-file file1)
1045
	  (mew-delete-file file2)
1046
	  (mew-delete-file file3)
1047
	  (mew-tinfo-set-privacy-err t)
1048
	  (mew-tinfo-set-privacy-type nil)
1049
	  (mew-draft-mode-name)
1050
	  (mew-encode-error errmsg))
1051
      ;; Create multipart content-header
1052
      (mew-header-insert mew-ct: (list ct
1053
				       (list "protocol" proto)
1054
				       (list "boundary" boundary)))
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
1055
      (mew-header-insert mew-cte: mew-7bit)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1056
      (insert (format "\n--%s\n" boundary))
1057
      ;; Insert control keys
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1058
      (mew-encode-singlepart
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1059
       (mew-encode-syntax-single file2 (list proto) cte2))
1060
      (insert (format "\n--%s\n" boundary))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1061
      ;; Insert encrypted body
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1062
      (mew-encode-singlepart
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1063
       (mew-encode-syntax-single file3 mew-type-apo cte3))
1064
      (insert (format "\n--%s--\n" boundary))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1065
      ;; Throw away the garbage
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1066
      (mew-delete-file file1)
1067
      (mew-delete-file file2)
1068
      (mew-delete-file file3))))
1069
1070
(defun mew-encode-multipart-signed (ct proto depth)
1071
  ;; called in the narrowed region
1072
  (let* ((boundary (mew-security-multipart-boundary depth))
1073
	 (switch mew-encode-multipart-signed-switch) ;; save length
1074
	 (func (mew-encode-get-security-func proto switch))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1075
	 (canon-func (mew-encode-get-canonicalize-func proto switch))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1076
	 file1 file2 micalg cte2 fmc errmsg ct2 cdp2)
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1077
    (if (fboundp canon-func) (funcall canon-func))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1078
    (setq file1 (mew-save-transfer-form (point-min) (point-max) 'retain))
1079
    ;; The narrowed region still the ORIGINAL part (i.e. line breaks are LF)
1080
    ;; Call the protocol function
1081
    (condition-case nil
1082
	(setq fmc (funcall func file1))
1083
      (error
1084
       (mew-delete-file file1)
1085
       (mew-encode-error
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1086
	(format "unknown error for %s. Check %s, anyway"
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1087
		mew-ct-mls mew-temp-dir))))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1088
    (mew-set '(file2 cte2 micalg errmsg ct2 cdp2) fmc)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1089
    (if errmsg
1090
	(progn
1091
	  (mew-delete-file file1)
1092
	  (mew-delete-file file2)
1093
	  (mew-tinfo-set-privacy-err t)
1094
	  (mew-tinfo-set-privacy-type nil)
1095
	  (mew-draft-mode-name)
1096
	  (mew-encode-error errmsg))
1097
      (goto-char (point-min))
1098
      ;; Before the signed part
1099
      ;; Create multipart content-header
1100
      (mew-header-insert mew-ct: (list ct
1101
				       (list "protocol" proto)
1102
				       (list "micalg" micalg)
1103
				       (list "boundary" boundary)))
1.2.1 by Tatsuya Kinoshita
Import upstream version 5.1.52~0.20061031
1104
      (mew-header-insert mew-cte: mew-7bit)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1105
      (insert (format "\n--%s\n" boundary))
1106
      (goto-char (point-max))
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1107
      ;; After the signed part
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1108
      (insert (format "\n--%s\n" boundary))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1109
      (mew-encode-singlepart
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1110
       (mew-encode-syntax-single file2 (or ct2 (list proto)) cte2 nil nil cdp2))
1111
      (insert (format "\n--%s--\n" boundary))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1112
      ;; Throw away the garbage
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1113
      (mew-delete-file file1)
1114
      (mew-delete-file file2))))
1115
1116
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1117
;;;
1118
;;; 8bit to 7bit conversion for Multipart/Security
1119
;;;
1120
1121
(defun mew-convert-mime-body (beg end cte linebasep)
1122
  (let* ((switch (if linebasep
1123
                     mew-prog-mime-encode-text-switch
1124
                   mew-prog-mime-encode-switch))
1125
	 file opt)
1126
    (save-restriction
1127
      (narrow-to-region beg end)
1128
      (cond
1129
       ((and (mew-case-equal cte mew-b64) (fboundp 'base64-encode-region))
1130
	(when linebasep
1131
	  (goto-char (point-min))
1132
	  (mew-lf-to-crlf))
1133
	(base64-encode-region (point-min) (point-max))
1134
	(goto-char (point-max))
1135
	(insert "\n"))
1136
       ((mew-which-exec mew-prog-mime-encode)
1137
	(setq opt (mew-prog-mime-encode-get-opt cte switch))
1138
	(if (null opt)
1139
	    (mew-encode-error (concat "Unknown CTE: " cte))
1140
	  (setq file (mew-make-temp-name))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1141
	  (mew-frwlet mew-cs-dummy (if linebasep mew-cs-text-for-write mew-cs-binary)
1142
	    ;; NEVER use call-process-region for privacy reasons
1143
	    (write-region (point-min) (point-max) file nil 'no-msg)
1144
	    (delete-region (point-min) (point-max)))
1145
	  (mew-piolet mew-cs-text-for-read mew-cs-dummy
1146
	    (apply 'call-process mew-prog-mime-encode file t nil opt))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1147
	  (mew-delete-file file)))
1148
       (t
1149
	(mew-encode-error (concat mew-prog-mime-encode " does not exist")))))))
1150
1151
(defun mew-convert-message ()
1152
  ;; called on the beginning of a header
1153
  (let ((case-fold-search t)
1154
	(buf (current-buffer))
1155
	hd-end mimep charset cte body-beg body-end)
1156
    (unless (re-search-forward mew-eoh nil t)
1157
      (goto-char (point-max)))
1158
    (setq hd-end (point-marker))
1159
    (goto-char (point-min))
1160
    (if (re-search-forward (concat "^" mew-mv:) (marker-position hd-end) t)
1161
	(setq mimep t))
1162
    (cond
1163
     (mimep
1164
      (goto-char (point-min))
1165
      (mew-convert-singlepart)
1166
      (mew-header-delete-lines (list mew-mv:))
1167
      (goto-char hd-end)
1168
      (mew-header-insert mew-mv: (concat mew-mv:-num " " mew-field-comment)))
1169
     (t
1.1.2 by Tatsuya Kinoshita
Import upstream version 5.0.53
1170
      (goto-char hd-end)
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1171
      (forward-line)
1172
      (setq body-beg (point))
1173
      (setq body-end (point-max))
1174
      (with-temp-buffer
1175
	(mew-insert-buffer-substring buf body-beg body-end)
1176
	(mew-cs-decode-region (point-min) (point-max) mew-cs-autoconv)
1177
	(setq charset (mew-charset-guess-region (point-min) (point-max))))
1178
      (when (mew-encode-charset-8bitp charset)
1179
	(setq cte (mew-charset-to-cte charset))
1180
	(if (null cte) (setq cte mew-b64))
1181
	(mew-convert-mime-body body-beg (point-max) cte 'linebasep)
1182
	(goto-char (point-min))
1183
	(mew-header-delete-lines (list "Content-"))
1184
	(goto-char hd-end)
1185
	(mew-header-insert mew-mv: mew-mv:-num)
1186
	(mew-header-insert mew-ct: (list mew-ct-txt (list "charset" charset)))
1187
	(mew-header-insert mew-cte: cte))))))
1188
1189
(defun mew-convert-singlepart (&optional dctl)
1190
  ;; called on the beginning of a content-header
1191
  (let ((case-fold-search t)
1192
	cthd-end ctbody-beg
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1193
	ct-val cte-val
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1194
	ctl ct cte charset)
1195
    (unless (re-search-forward mew-eoh nil t)
1196
      (goto-char (point-max)))
1197
    (setq cthd-end (point-marker))
1198
    (forward-line)
1199
    (setq ctbody-beg (point))
1200
    (goto-char (point-min))
1201
    (if (not (re-search-forward (concat "^" mew-cte: "[ \t]*") nil t))
1202
	(setq cte mew-7bit)
1203
      (setq cte-val (point-marker))
1204
      (forward-line)
1205
      (mew-header-goto-next)
1206
      (setq cte (mew-addrstr-parse-value
1207
		 (mew-buffer-substring cte-val (1- (point))))))
1208
    (when (or (mew-case-equal cte mew-8bit) (mew-case-equal cte mew-bin))
1209
      (goto-char (point-min))
1210
      (if (not (re-search-forward (concat "^" mew-ct: "[ \t]*") nil t))
1211
	  (setq ctl (or dctl mew-type-txt))
1212
	(setq ct-val (point))
1213
	(forward-line)
1214
	(mew-header-goto-next)
1215
	(setq ctl (mew-param-decode
1216
		   (mew-buffer-substring ct-val (1- (point)))))
1217
	(setq ct (mew-syntax-get-value ctl 'cap))
1218
	(cond
1219
	 ((mew-ct-multipartp ct)
1220
	  (if (or (string= ct mew-ct-mle) (string= ct mew-ct-mls))
1221
	      ()
1222
	    (mew-convert-multipart ctl))
1223
	  (setq cte mew-7bit))
1224
	 ((mew-ct-messagep ct)
1225
	  (if (string= ct mew-ct-msg)
1226
	      (mew-convert-message))
1227
	  (setq cte mew-7bit))
1228
	 ((mew-ct-textp ct)
1229
	  (setq charset (mew-syntax-get-param ctl "charset"))
1230
	  (setq cte (mew-charset-to-cte charset))
1231
	  (if (or (null cte)
1232
		  (mew-case-equal cte mew-8bit)
1233
		  (mew-case-equal cte mew-bin))
1234
	      (setq cte mew-b64))
1235
	  (unless (mew-case-equal cte mew-7bit)
1236
	    (mew-convert-mime-body ctbody-beg (point-max) cte 'linebasep)))
1237
	 (t
1238
	  ;; rare case
1239
	  (setq cte (mew-ctdb-cte (mew-ctdb-by-ct ct)))
1240
	  (if (or (null cte)
1241
		  (mew-case-equal cte mew-8bit)
1242
		  (mew-case-equal cte mew-bin))
1243
	      (setq cte mew-b64))
1244
	  (unless (mew-case-equal cte mew-7bit)
1245
	    (mew-convert-mime-body
1246
	     ctbody-beg (point-max) cte (mew-ct-linebasep ct))))
1247
	 (goto-char (point-min)))
1248
	(mew-header-delete-lines (list mew-cte:))
1249
	(goto-char cthd-end)
1250
	(mew-header-insert mew-cte: (concat cte " " mew-field-comment))))))
1251
1252
(defun mew-convert-multipart (ctl)
1253
  (let* ((case-fold-search nil) ;; boundary is case sensitive
1254
	 (ct (mew-syntax-get-value ctl 'cap))
1255
	 (dctl (if (string= ct mew-ct-mld) mew-type-msg))
1256
	 (boundary (regexp-quote (mew-syntax-get-param ctl "boundary")))
1257
	 obound ebound bregex start break)
1258
    (unless boundary
1259
      (mew-encode-error "No boundary parameter for multipart"))
1260
    (setq obound (concat "--" boundary))
1261
    (setq ebound (concat "--" boundary "--"))
1262
    (setq bregex (concat "^--" boundary "\\(\\|--\\)$"))
1263
    (unless (re-search-forward (concat "^" obound "$") nil t)
1264
      (mew-encode-error (format "No first boundary for %s" ct)))
1265
    (forward-line)
1266
    (setq start (point)) ;; the beginning of the part
1267
    (catch 'multipart
1268
      (while t
1269
	(unless (re-search-forward bregex nil t)
1270
	  (mew-encode-error (format "No last boundary for %s" ct)))
1271
	(setq break (string= (regexp-quote (match-string 0)) ebound))
1272
	(forward-line) ;; the beginning of the next part
1273
	(save-excursion
1274
	  (forward-line -1)
1275
	  (beginning-of-line) ;; just in case
1.1.1 by Tatsuya Kinoshita
Import upstream version 4.2.52
1276
	  (forward-char -1) ;; skip the preceding CRLF
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1277
	  ;; the end of the part
1278
	  (save-restriction
1279
	    (narrow-to-region start (point))
1280
	    (goto-char (point-min))
1281
	    ;; the beginning of the part
1282
	    (mew-convert-singlepart dctl)))
1283
	(setq start (point)) ;; the beginning of the part
1284
	(if break (throw 'multipart nil))))))
1285
1286
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1287
;;;
1288
;;; Backup and undo
1289
;;;
1290
1291
(defun mew-encode-make-backup ()
1292
  (let* ((file (buffer-file-name))
1293
	 (back (mew-prepend-prefix file mew-backup-prefix))
1294
	 (info (concat file mew-draft-info-suffix)))
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1295
    (mew-frwlet mew-cs-dummy mew-cs-m17n
1296
      (write-region (point-min) (point-max) back nil 'no-msg))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1297
    (mew-lisp-save
1298
     info
1299
     (list
1300
      (cons "Syntax:" mew-encode-syntax)
1301
      (cons "Case:" (mew-tinfo-get-case))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
1302
      (cons "Flowed:" (mew-tinfo-get-flowed))
1303
      (cons "Use-Flowed:" (mew-tinfo-get-use-flowed))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1304
      (cons "Message:" (mew-tinfo-get-hdr-file))) ;; Header mode
1305
     'nobackup)
1306
    nil)) ;; to save
1307
1308
(defun mew-encode-load-syntax ()
1309
  (let* ((file (buffer-file-name))
1310
	 (info (concat file mew-draft-info-suffix))
1311
	 syntax)
1312
    (when (file-exists-p info)
1313
      (setq syntax (mew-lisp-load info))
1314
      (setq mew-encode-syntax (cdr (assoc "Syntax:" syntax)))
1315
      (if (and mew-encode-syntax
1316
	       (mew-syntax-singlepart-p mew-encode-syntax))
1317
	  (setq mew-encode-syntax nil))
1318
      (mew-tinfo-set-case (cdr (assoc "Case:" syntax)))
1.2.3 by Tatsuya Kinoshita
Import upstream version 6.2.51
1319
      (mew-tinfo-set-flowed (cdr (assoc "Flowed:" syntax)))
1320
      (mew-tinfo-set-flowed (cdr (assoc "Use-Flowed:" syntax)))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1321
      (mew-tinfo-set-hdr-file (cdr (assoc "Message:" syntax))) ;; Header mode
1322
      t)))
1323
1324
(defun mew-encode-insert-backup ()
1325
  (let* ((file (buffer-file-name))
1326
	 (back (mew-prepend-prefix file mew-backup-prefix)))
1327
    (when (file-exists-p back)
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1328
      (mew-frwlet mew-cs-m17n mew-cs-dummy
1329
	(mew-insert-file-contents back)))))
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1330
1331
(defun mew-encode-undo ()
1332
  "Get back to the draft before making MIME message."
1333
  (interactive)
1334
  (mew-elet
1335
   (if (not (mew-encode-load-syntax))
1336
       (message "Cannot undo")
1337
     (mew-erase-buffer)
1338
     (if (not (mew-encode-insert-backup))
1339
	 (message "Cannot undo")
1340
       (mew-header-clear) ;; erase the old header separator
1341
       (mew-header-prepared)
1342
       (if mew-encode-syntax (mew-draft-prepare-attachments))
1343
       (mew-draft-toolbar-update)
1344
       (setq buffer-undo-list nil)))))
1345
1346
(provide 'mew-encode)
1347
1348
;;; Copyright Notice:
1349
1.2.5 by Tatsuya Kinoshita
Import upstream version 7.0.50~0.20100105
1350
;; Copyright (C) 1996-2010 Mew developing team.
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1351
;; All rights reserved.
1352
1353
;; Redistribution and use in source and binary forms, with or without
1354
;; modification, are permitted provided that the following conditions
1355
;; are met:
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1356
;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1357
;; 1. Redistributions of source code must retain the above copyright
1358
;;    notice, this list of conditions and the following disclaimer.
1359
;; 2. Redistributions in binary form must reproduce the above copyright
1360
;;    notice, this list of conditions and the following disclaimer in the
1361
;;    documentation and/or other materials provided with the distribution.
1362
;; 3. Neither the name of the team nor the names of its contributors
1363
;;    may be used to endorse or promote products derived from this software
1364
;;    without specific prior written permission.
1.1.12 by Tatsuya Kinoshita
Import upstream version 6.0.51~0.20080421
1365
;;
1 by Tatsuya Kinoshita
Import upstream version 4.0.65
1366
;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
1367
;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1368
;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1369
;; PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
1370
;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1371
;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1372
;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1373
;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1374
;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
1375
;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
1376
;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1377
1378
;;; mew-encode.el ends here