* elmo-imap4.el (elmo-imap4-decode-folder-string): Call `utf7-decode'.
[elisp/wanderlust.git] / elmo / elmo-maildir.el
index 74a7405..29de0b7 100644 (file)
                                    (unread ?S 'remove)
                                    (answered ?R)))
 
+;; Decided at compile time.
+(defcustom elmo-maildir-separator
+  (if (memq system-type '(windows-nt)) ?\- ?:)
+  "Character separating the id section from the flags section.
+According to the maildir specification, this should be a colon (?:),
+but some file systems don't support colons in filenames."
+  :type 'character
+  :group 'elmo)
+
+(defmacro elmo-maildir-adjust-separator (string)
+  `(if (= elmo-maildir-separator ?:)
+       ,string
+     (elmo-replace-in-string
+      ,string ":" (char-to-string elmo-maildir-separator))))
+
 ;;; ELMO Maildir folder
 (eval-and-compile
   (luna-define-class elmo-maildir-folder
@@ -101,7 +116,9 @@ LOCATION."
     (setq locations
          (mapcar
           (lambda (x)
-            (if (string-match "^\\([^:]+\\):\\([^:]+\\)$" x)
+            (if (string-match
+                 (elmo-maildir-adjust-separator "^\\([^:]+\\):\\([^:]+\\)$")
+                 x)
                 (progn
                   (setq sym (elmo-match-string 1 x)
                         flag-list (string-to-char-list
@@ -260,14 +277,18 @@ LOCATION."
        (expand-file-name (car news) (expand-file-name "new" maildir))
        (expand-file-name (concat
                          (car news)
-                         (unless (string-match ":2,[A-Z]*$" (car news))
-                           ":2,"))
+                         (unless (string-match
+                                  (elmo-maildir-adjust-separator ":2,[A-Z]*$")
+                                  (car news))
+                           (elmo-maildir-adjust-separator  ":2,")))
                         (expand-file-name "cur" maildir)))
       (setq news (cdr news)))))
 
 (defun elmo-maildir-set-mark (filename mark)
   "Mark the FILENAME file in the maildir.  MARK is a character."
-  (if (string-match "^\\([^:]+:[12],\\)\\(.*\\)$" filename)
+  (if (string-match
+       (elmo-maildir-adjust-separator "^\\([^:]+:[12],\\)\\(.*\\)$")
+       filename)
       (let ((flaglist (string-to-char-list (elmo-match-string
                                            2 filename))))
        (unless (memq mark flaglist)
@@ -277,12 +298,15 @@ LOCATION."
                               (char-list-to-string flaglist)))))
     ;; Rescue no info file in maildir.
     (rename-file filename
-                (concat filename ":2," (char-to-string mark))))
+                (concat filename
+                        (elmo-maildir-adjust-separator ":2,")
+                        (char-to-string mark))))
   t)
 
 (defun elmo-maildir-delete-mark (filename mark)
   "Mark the FILENAME file in the maildir.  MARK is a character."
-  (if (string-match "^\\([^:]+:2,\\)\\(.*\\)$" filename)
+  (if (string-match (elmo-maildir-adjust-separator "^\\([^:]+:2,\\)\\(.*\\)$")
+                   filename)
       (let ((flaglist (string-to-char-list (elmo-match-string
                                            2 filename))))
        (when (memq mark flaglist)
@@ -393,7 +417,7 @@ file name for maildir directories."
     filename))
 
 (luna-define-method elmo-folder-append-buffer ((folder elmo-maildir-folder)
-                                              &optional flag number)
+                                              &optional flags number)
   (let ((basedir (elmo-maildir-folder-directory-internal folder))
        (src-buf (current-buffer))
        dst-buf filename)
@@ -406,11 +430,15 @@ file name for maildir directories."
          (as-binary-output-file
           (write-region (point-min) (point-max) filename nil 'no-msg))
          ;; add link from new.
-         (elmo-add-name-to-file
+         ;; Some filesystem (like AFS) does not have hard-link.
+         ;; So we use elmo-copy-file instead of elmo-add-name-to-file here.
+         (elmo-copy-file
           filename
           (expand-file-name
            (concat "new/" (file-name-nondirectory filename))
            basedir))
+         (elmo-folder-preserve-flags
+          folder (elmo-msgdb-get-message-id-from-buffer) flags)
          t)
       ;; If an error occured, return nil.
       (error))))
@@ -449,7 +477,7 @@ file name for maildir directories."
   (if (elmo-folder-message-file-p src-folder)
       (let ((src-msgdb-exists (not (zerop (elmo-folder-length src-folder))))
            (dir (elmo-maildir-folder-directory-internal folder))
-           (table (elmo-flag-table-load (elmo-folder-msgdb-path folder)))
+           (table (elmo-folder-flag-table folder))
            (succeeds numbers)
            filename flags id)
        (dolist (number numbers)
@@ -458,7 +486,9 @@ file name for maildir directories."
          (elmo-copy-file
           (elmo-message-file-name src-folder number)
           filename)
-         (elmo-add-name-to-file
+         ;; Some filesystem (like AFS) does not have hard-link.
+         ;; So we use elmo-copy-file instead of elmo-add-name-to-file here.
+         (elmo-copy-file
           filename
           (expand-file-name
            (concat "new/" (file-name-nondirectory filename))
@@ -470,7 +500,7 @@ file name for maildir directories."
            (elmo-flag-table-set table id flags))
          (elmo-progress-notify 'elmo-folder-move-messages))
        (when (elmo-folder-persistent-p folder)
-         (elmo-flag-table-save (elmo-folder-msgdb-path folder) table))
+         (elmo-folder-close-flag-table folder))
        succeeds)
     (luna-call-next-method)))
 
@@ -482,14 +512,18 @@ file name for maildir directories."
       (if (and file
               (file-writable-p file)
               (not (file-directory-p file)))
-         (delete-file file)))))
+         (delete-file file))))
+  t)
 
 (luna-define-method elmo-map-message-fetch ((folder elmo-maildir-folder)
                                            location strategy
                                            &optional section unseen)
   (let ((file (elmo-maildir-message-file-name folder location)))
     (when (file-exists-p file)
-      (insert-file-contents-as-binary file))))
+      (insert-file-contents-as-binary file)
+      (unless unseen
+       (elmo-map-folder-set-flag folder (list location) 'read))
+      t)))
 
 (luna-define-method elmo-folder-exists-p ((folder elmo-maildir-folder))
   (let ((basedir (elmo-maildir-folder-directory-internal folder)))