2003-07-15 Mito <mito@mxa.nes.nec.co.jp>
[elisp/wanderlust.git] / elmo / elmo-archive.el
index eb3e895..f76d026 100644 (file)
@@ -1,4 +1,4 @@
-;;; elmo-archive.el -- Archive folder of ELMO.
+;;; elmo-archive.el --- Archive folder of ELMO. -*- coding: euc-japan -*-
 
 ;; Copyright (C) 1998,1999,2000 OKUNISHI Fujikazu <fuji0924@mbox.kyoto-inet.or.jp>
 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
 ;;; ELMO Local directory folder
 (eval-and-compile
   (luna-define-class elmo-archive-folder (elmo-folder)
-                    (archive-name archive-type archive-prefix))
+                    (archive-name archive-type archive-prefix dir-name))
   (luna-define-internal-accessors 'elmo-archive-folder))
 
+(luna-define-generic elmo-archive-folder-path (folder)
+  "Return local directory path of the FOLDER.")
+
+(luna-define-method elmo-archive-folder-path ((folder elmo-archive-folder))
+  elmo-archive-folder-path)
+
 (luna-define-method elmo-folder-initialize ((folder
                                             elmo-archive-folder)
                                            name)
+  (elmo-archive-folder-set-dir-name-internal folder name)
   (when (string-match
         "^\\([^;]*\\);?\\([^;]*\\);?\\([^;]*\\)$"
         name)
                             (symbol-name
                              (elmo-archive-folder-archive-type-internal
                               folder)))
-                    elmo-msgdb-dir)))
+                    elmo-msgdb-directory)))
 
 ;;; MMDF parser -- info-zip agent w/ REXX
 (defvar elmo-mmdf-delimiter "^\01\01\01\01$"
   (` (cdr (assq (, type)
                elmo-archive-file-regexp-alist))))
 
-(static-if (boundp 'NEMACS)
-    (defsubst elmo-archive-call-process (prog args &optional output)
-      (apply 'call-process prog nil output nil args)
-      0)
-  (defsubst elmo-archive-call-process (prog args &optional output)
-    (= (apply 'call-process prog nil output nil args) 0)))
+(defsubst elmo-archive-call-process (prog args &optional output)
+  (= (apply 'call-process prog nil output nil args) 0))
 
 (defsubst elmo-archive-call-method (method args &optional output)
   (cond
@@ -306,7 +309,7 @@ TYPE specifies the archiver's symbol."
                      (not (eobp)))  ; for GNU tar 981010
            (setq file-list (nconc file-list (list (string-to-int
                                                    (match-string 1)))))))
-      (error "%s does not exist." file))
+      (error "%s does not exist" file))
     (if nonsort
        (cons (or (elmo-max-of-list file-list) 0)
              (if killed
@@ -445,16 +448,28 @@ TYPE specifies the archiver's symbol."
        ))))
 
 (luna-define-method elmo-folder-delete ((folder elmo-archive-folder))
-  (let ((arc (elmo-archive-get-archive-name folder)))
-    (if (not (file-exists-p arc))
-       (error "No such file: %s" arc)
-      (delete-file arc)
-      t)))
+  (let ((msgs (and (elmo-folder-exists-p folder)
+                  (elmo-folder-list-messages folder))))
+    (when (yes-or-no-p (format "%sDelete msgdb and substance of \"%s\"? "
+                              (if (> (length msgs) 0)
+                                  (format "%d msg(s) exists. " (length msgs))
+                                "")
+                              (elmo-folder-name-internal folder)))
+      (let ((arc (elmo-archive-get-archive-name folder)))
+       (if (not (file-exists-p arc))
+           (error "No such file: %s" arc)
+         (delete-file arc))
+       (elmo-msgdb-delete-path folder)
+       t))))
 
 (luna-define-method elmo-folder-rename-internal ((folder elmo-archive-folder)
                                                 new-folder)
   (let* ((old-arc (elmo-archive-get-archive-name folder))
-        (new-arc (elmo-archive-get-archive-name new-folder)))
+        (new-arc (elmo-archive-get-archive-name new-folder))
+        (new-dir (directory-file-name
+                  (elmo-archive-get-archive-directory new-folder))))
+    (if elmo-archive-treat-file
+       (setq new-dir (directory-file-name (file-name-directory new-dir))))
     (unless (and (eq (elmo-archive-folder-archive-type-internal folder)
                     (elmo-archive-folder-archive-type-internal new-folder))
                 (equal (elmo-archive-folder-archive-prefix-internal
@@ -462,12 +477,14 @@ TYPE specifies the archiver's symbol."
                        (elmo-archive-folder-archive-prefix-internal
                         new-folder)))
       (error "Not same archive type and prefix"))
-    (if (not (file-exists-p old-arc))
-       (error "No such file: %s" old-arc)
-      (if (file-exists-p new-arc)
-         (error "Already exists: %s" new-arc)
-       (rename-file old-arc new-arc)
-       t))))
+    (unless (file-exists-p old-arc)
+      (error "No such file: %s" old-arc))
+    (when (file-exists-p new-arc)
+      (error "Already exists: %s" new-arc))
+    (unless (file-directory-p new-dir)
+      (elmo-make-directory new-dir))
+    (rename-file old-arc new-arc)
+    t))
 
 (defun elmo-archive-folder-list-subfolders (folder one-level)
   (if elmo-archive-treat-file
@@ -489,7 +506,9 @@ TYPE specifies the archiver's symbol."
                       "" (file-name-nondirectory path)))
             (flist (and (file-directory-p dir)
                         (directory-files dir nil
-                                         (concat "^" name "[^A-z][^A-z]")
+                                         (if (> (length name) 0)
+                                             (concat "^" name "[^A-z][^A-z]")
+                                           name)
                                          nil)))
             (regexp (format "^\\(.*\\)\\(%s\\)$"
                             (mapconcat
@@ -515,10 +534,20 @@ TYPE specifies the archiver's symbol."
                       suffix prefix)))
          flist)))
     (elmo-mapcar-list-of-list
-     (function (lambda (x) (concat (elmo-folder-prefix-internal folder) x)))
+     (function (lambda (x)
+                (if (file-exists-p
+                     (expand-file-name
+                      (concat elmo-archive-basename
+                              (elmo-archive-get-suffix
+                               (elmo-archive-folder-archive-type-internal
+                                folder)))
+                      (expand-file-name
+                       x
+                       (elmo-archive-folder-path folder))))
+                    (concat (elmo-folder-prefix-internal folder) x))))
      (elmo-list-subdirectories
-      (elmo-archive-get-archive-directory folder)
-      ""
+      (elmo-archive-folder-path folder)
+      (or (elmo-archive-folder-dir-name-internal folder) "")
       one-level))))
 
 (luna-define-method elmo-folder-list-subfolders ((folder elmo-archive-folder)
@@ -536,11 +565,12 @@ TYPE specifies the archiver's symbol."
         (method (elmo-archive-get-method type 'cat))
         (args (list arc (elmo-concat-path
                          prefix (int-to-string number)))))
-    (when (file-exists-p arc)
-      (and
-       (as-binary-process
-       (elmo-archive-call-method method args t))
-       (elmo-delete-cr-buffer)))))
+    (and (file-exists-p arc)
+        (as-binary-process
+         (elmo-archive-call-method method args t))
+        (progn
+          (elmo-delete-cr-buffer)
+          t))))
 
 (luna-define-method elmo-message-fetch-internal ((folder elmo-archive-folder)
                                                 number strategy
@@ -594,51 +624,53 @@ TYPE specifies the archiver's symbol."
   ((folder elmo-archive-folder) src-folder numbers unread-marks
    &optional same-number)
   (let ((prefix (elmo-archive-folder-archive-prefix-internal folder)))
-  (cond
-   ((and same-number
-        (null prefix)
-        (elmo-folder-message-file-p src-folder)
-        (elmo-folder-message-file-number-p src-folder))
-    ;; same-number(localdir, localnews) -> archive
-    (elmo-archive-append-files folder
-                              (elmo-folder-message-file-directory src-folder)
-                              numbers)
-    numbers)
-   ((elmo-folder-message-make-temp-file-p src-folder)
-    ;; not-same-number (localdir, localnews), (archive maildir) -> archive
-    (let ((temp-dir (elmo-folder-message-make-temp-files
-                    src-folder
-                    numbers
-                    (unless same-number
-                      (1+ (if (file-exists-p (elmo-archive-get-archive-name
-                                              folder))
-                              (car (elmo-folder-status folder)) 0)))))
-         new-dir base-dir files)
-      (setq base-dir temp-dir)
-      (when (> (length prefix) 0)
-       (when (file-name-directory prefix)
-         (elmo-make-directory (file-name-directory prefix)))
-       (rename-file
-        temp-dir
-        (setq new-dir
-              (expand-file-name
-               prefix
-               ;; parent of temp-dir..(works in windows?)
-               (expand-file-name ".." temp-dir))))
-       ;; now temp-dir has name prefix.
-       (setq temp-dir new-dir)
-       ;; parent of prefix becomes base-dir.
-       (setq base-dir (expand-file-name ".." temp-dir)))
-      (setq files
-           (mapcar
-            '(lambda (x) (elmo-concat-path prefix x))
-            (directory-files temp-dir nil "^[^\\.]")))
-      (if (elmo-archive-append-files folder
-                                    base-dir
-                                    files)
-         (elmo-delete-directory temp-dir)))
-    numbers)
-   (t (luna-call-next-method)))))
+    (cond
+     ((and same-number
+          (null prefix)
+          (elmo-folder-message-file-p src-folder)
+          (elmo-folder-message-file-number-p src-folder))
+      ;; same-number(localdir, localnews) -> archive
+      (elmo-archive-append-files folder
+                                (elmo-folder-message-file-directory src-folder)
+                                numbers)
+      (elmo-progress-notify 'elmo-folder-move-messages (length numbers))
+      numbers)
+     ((elmo-folder-message-make-temp-file-p src-folder)
+      ;; not-same-number (localdir, localnews), (archive maildir) -> archive
+      (let ((temp-dir (elmo-folder-message-make-temp-files
+                      src-folder
+                      numbers
+                      (unless same-number
+                        (1+ (if (file-exists-p (elmo-archive-get-archive-name
+                                                folder))
+                                (car (elmo-folder-status folder)) 0)))))
+           new-dir base-dir files)
+       (setq base-dir temp-dir)
+       (when (> (length prefix) 0)
+         (when (file-name-directory prefix)
+           (elmo-make-directory (file-name-directory prefix)))
+         (rename-file
+          temp-dir
+          (setq new-dir
+                (expand-file-name
+                 prefix
+                 ;; parent of temp-dir..(works in windows?)
+                 (expand-file-name ".." temp-dir))))
+         ;; now temp-dir has name prefix.
+         (setq temp-dir new-dir)
+         ;; parent of prefix becomes base-dir.
+         (setq base-dir (expand-file-name ".." temp-dir)))
+       (setq files
+             (mapcar
+              '(lambda (x) (elmo-concat-path prefix x))
+              (directory-files temp-dir nil "^[^\\.]")))
+       (if (elmo-archive-append-files folder
+                                      base-dir
+                                      files)
+           (elmo-delete-directory temp-dir)))
+      (elmo-progress-notify 'elmo-folder-move-messages (length numbers))
+      numbers)
+     (t (luna-call-next-method)))))
 
 (luna-define-method elmo-folder-message-make-temp-file-p
   ((folder elmo-archive-folder))
@@ -654,8 +686,8 @@ TYPE specifies the archiver's symbol."
 (defun elmo-archive-folder-message-make-temp-files (folder
                                                    numbers
                                                    start-number)
-  (let* ((tmp-dir-src (elmo-folder-make-temp-dir folder))
-        (tmp-dir-dst (elmo-folder-make-temp-dir folder))
+  (let* ((tmp-dir-src (elmo-folder-make-temporary-directory folder))
+        (tmp-dir-dst (elmo-folder-make-temporary-directory folder))
         (arc     (elmo-archive-get-archive-name folder))
         (type    (elmo-archive-folder-archive-type-internal folder))
         (prefix  (elmo-archive-folder-archive-prefix-internal folder))
@@ -756,14 +788,10 @@ TYPE specifies the archiver's symbol."
           (error "WARNING: not delete: %s (method undefined)" type)))))
 
 (defun elmo-archive-exec-msgs-subr1 (prog args msgs)
-  (let ((buf (get-buffer-create " *ELMO ARCHIVE exec*")))
-    (set-buffer buf)
+  (with-temp-buffer
     (insert (mapconcat 'concat msgs "\n")) ;string
-    (unwind-protect
-       (= 0
-          (apply 'call-process-region (point-min) (point-max)
-                 prog nil nil nil args))
-      (kill-buffer buf))))
+    (= 0 (apply 'call-process-region (point-min) (point-max)
+               prog nil nil nil args))))
 
 (defun elmo-archive-exec-msgs-subr2 (prog args msgs arc-length)
   (let ((max-len (- elmo-archive-cmdstr-max-length arc-length))
@@ -845,7 +873,7 @@ TYPE specifies the archiver's symbol."
      (setq ret-val
           (elmo-archive-call-process
            (car compress) (append (cdr compress) (list arc-tar)))))
-    ;; delete tmporary messages
+    ;; delete temporary messages
     (if (and (not copy)
             (eq exec-type 'append))
        (while tmp-msgs