comparison lisp/arc-mode.el @ 21570:e21c343b0c6e

(archive-extract-by-stdout): Don't use binary-process-output. Bind coding-system-for-read to 'undecided, so coding system is determined on the fly. Bind inherit-process-coding-system to t. (archive-dos-members): Remove. (archive-extract): Don't call archive-check-dos. Handle pkunzip errors. (archive-*-extract): Handle pkzip errors. (archive-check-dos): Remove. (archive-subfile-dos): Remove. (archive-extract): Don't bind archive-subfile-dos. (archive-write-file-member): Don't DOSify DOS-style archive members. (archive-zip-extract): Make pkzip use -o- flag, to make it more silent.
author Eli Zaretskii <eliz@gnu.org>
date Wed, 15 Apr 1998 15:31:30 +0000
parents ad6c6f1bd674
children 029145c16497
comparison
equal deleted inserted replaced
21569:c1f86e273a38 21570:e21c343b0c6e
117 117
118 (defgroup archive-zoo nil 118 (defgroup archive-zoo nil
119 "ZOO-specific options to archive." 119 "ZOO-specific options to archive."
120 :group 'archive) 120 :group 'archive)
121 121
122
123 (defcustom archive-dos-members t
124 "*If non-nil then recognize member files using ^M^J as line terminator."
125 :type 'boolean
126 :group 'archive)
127
128 (defcustom archive-tmpdir 122 (defcustom archive-tmpdir
129 (expand-file-name 123 (expand-file-name
130 (make-temp-name (if (eq system-type 'ms-dos) "ar" "archive.tmp")) 124 (make-temp-name (if (eq system-type 'ms-dos) "ar" "archive.tmp"))
131 (or (getenv "TMPDIR") (getenv "TMP") "/tmp")) 125 (or (getenv "TMPDIR") (getenv "TMP") "/tmp"))
132 "*Directory for temporary files made by arc-mode.el" 126 "*Directory for temporary files made by arc-mode.el"
220 Only set to true for msdog systems!" 214 Only set to true for msdog systems!"
221 :type 'boolean 215 :type 'boolean
222 :group 'archive-zip) 216 :group 'archive-zip)
223 217
224 (defcustom archive-zip-extract 218 (defcustom archive-zip-extract
225 (if archive-zip-use-pkzip '("pkunzip" "-e") '("unzip" "-qq" "-c")) 219 (if archive-zip-use-pkzip '("pkunzip" "-e" "-o-") '("unzip" "-qq" "-c"))
226 "*Program and its options to run in order to extract a zip file member. 220 "*Program and its options to run in order to extract a zip file member.
227 Extraction should happen to standard output. Archive and member name will 221 Extraction should happen to standard output. Archive and member name will
228 be added. If `archive-zip-use-pkzip' is non-nil then this program is 222 be added. If `archive-zip-use-pkzip' is non-nil then this program is
229 expected to extract to a file junking the directory part of the name." 223 expected to extract to a file junking the directory part of the name."
230 :type '(list (string :tag "Program") 224 :type '(list (string :tag "Program")
331 (put 'archive-superior-buffer 'permanent-local t) 325 (put 'archive-superior-buffer 'permanent-local t)
332 326
333 (defvar archive-subfile-mode nil "*Non-nil in archive member buffers.") 327 (defvar archive-subfile-mode nil "*Non-nil in archive member buffers.")
334 (make-variable-buffer-local 'archive-subfile-mode) 328 (make-variable-buffer-local 'archive-subfile-mode)
335 (put 'archive-subfile-mode 'permanent-local t) 329 (put 'archive-subfile-mode 'permanent-local t)
336
337 (defvar archive-subfile-dos nil
338 "Negation of `buffer-file-type', which see.")
339 (make-variable-buffer-local 'archive-subfile-dos)
340 (put 'archive-subfile-dos 'permanent-local t)
341 330
342 (defvar archive-files nil 331 (defvar archive-files nil
343 "Vector of file descriptors. 332 "Vector of file descriptors.
344 Each descriptor is a vector of the form 333 Each descriptor is a vector of the form
345 [EXT-FILE-NAME INT-FILE-NAME CASE-FIDDLED MODE ...]") 334 [EXT-FILE-NAME INT-FILE-NAME CASE-FIDDLED MODE ...]")
526 ;; Real file contents is binary 515 ;; Real file contents is binary
527 (make-local-variable 'require-final-newline) 516 (make-local-variable 'require-final-newline)
528 (setq require-final-newline nil) 517 (setq require-final-newline nil)
529 (make-local-variable 'enable-local-variables) 518 (make-local-variable 'enable-local-variables)
530 (setq enable-local-variables nil) 519 (setq enable-local-variables nil)
531 (if (boundp 'default-buffer-file-type)
532 (setq buffer-file-type t))
533 520
534 (make-local-variable 'archive-read-only) 521 (make-local-variable 'archive-read-only)
535 (setq archive-read-only (not (file-writable-p (buffer-file-name)))) 522 (setq archive-read-only (not (file-writable-p (buffer-file-name))))
536 523
537 ;; Should we use a local copy when accessing from outside Emacs? 524 ;; Should we use a local copy when accessing from outside Emacs?
655 (define-key archive-mode-map [menu-bar operate expunge] 642 (define-key archive-mode-map [menu-bar operate expunge]
656 '("Expunge Marked Files" . archive-expunge)) 643 '("Expunge Marked Files" . archive-expunge))
657 )) 644 ))
658 645
659 (let* ((item1 '(archive-subfile-mode " Archive")) 646 (let* ((item1 '(archive-subfile-mode " Archive"))
660 (item2 '(archive-subfile-dos " Dos")) 647 (items (list item1)))
661 (items (if (memq system-type '(ms-dos windows-nt))
662 (list item1) ; msdog has its own indicator
663 (list item1 item2))))
664 (or (member item1 minor-mode-alist) 648 (or (member item1 minor-mode-alist)
665 (setq minor-mode-alist (append items minor-mode-alist)))) 649 (setq minor-mode-alist (append items minor-mode-alist))))
666 ;; ------------------------------------------------------------------------- 650 ;; -------------------------------------------------------------------------
667 (defun archive-find-type () 651 (defun archive-find-type ()
668 (widen) 652 (widen)
828 (make-local-variable 'archive-superior-buffer) 812 (make-local-variable 'archive-superior-buffer)
829 (setq archive-superior-buffer archive-buffer) 813 (setq archive-superior-buffer archive-buffer)
830 (make-local-variable 'local-write-file-hooks) 814 (make-local-variable 'local-write-file-hooks)
831 (add-hook 'local-write-file-hooks 'archive-write-file-member) 815 (add-hook 'local-write-file-hooks 'archive-write-file-member)
832 (setq archive-subfile-mode descr) 816 (setq archive-subfile-mode descr)
833 (setq archive-subfile-dos nil) 817 ; (if (boundp 'default-buffer-file-type)
834 (if (boundp 'default-buffer-file-type) 818 ; (setq buffer-file-type t))
835 (setq buffer-file-type t)) 819 (if (and
836 (if (fboundp extractor) 820 (null
837 (funcall extractor archive ename) 821 (if (fboundp extractor)
838 (archive-*-extract archive ename (symbol-value extractor))) 822 (funcall extractor archive ename)
839 (if archive-dos-members (archive-check-dos)) 823 (archive-*-extract archive ename (symbol-value extractor))))
840 (goto-char (point-min)) 824 just-created)
841 (rename-buffer bufname) 825 (progn
842 (setq buffer-read-only read-only-p) 826 (set-buffer-modified-p nil)
843 (setq buffer-undo-list nil) 827 (kill-buffer buffer))
844 (set-buffer-modified-p nil) 828 (goto-char (point-min))
845 (setq buffer-saved-size (buffer-size)) 829 (rename-buffer bufname)
846 (normal-mode) 830 (setq buffer-read-only read-only-p)
847 ;; Just in case an archive occurs inside another archive. 831 (setq buffer-undo-list nil)
848 (if (eq major-mode 'archive-mode) 832 (set-buffer-modified-p nil)
849 (setq archive-remote t)) 833 (setq buffer-saved-size (buffer-size))
850 (run-hooks 'archive-extract-hooks)) 834 (normal-mode)
851 (archive-maybe-update t)) 835 ;; Just in case an archive occurs inside another archive.
852 (if view-p 836 (if (eq major-mode 'archive-mode)
853 (view-buffer buffer (and just-created 'kill-buffer)) 837 (setq archive-remote t))
854 (if (eq other-window-p 'display) 838 (run-hooks 'archive-extract-hooks))
855 (display-buffer buffer) 839 (archive-maybe-update t)))
856 (if other-window-p 840 (or (not (buffer-name buffer))
857 (switch-to-buffer-other-window buffer) 841 (progn
858 (switch-to-buffer buffer)))))) 842 (if view-p
843 (view-buffer buffer (and just-created 'kill-buffer)))
844 (if (eq other-window-p 'display)
845 (display-buffer buffer)
846 (if other-window-p
847 (switch-to-buffer-other-window buffer)
848 (switch-to-buffer buffer)))))))
859 849
860 (defun archive-*-extract (archive name command) 850 (defun archive-*-extract (archive name command)
861 (let* ((default-directory (file-name-as-directory archive-tmpdir)) 851 (let* ((default-directory (file-name-as-directory archive-tmpdir))
862 (tmpfile (expand-file-name (file-name-nondirectory name) 852 (tmpfile (expand-file-name (file-name-nondirectory name)
863 default-directory))) 853 default-directory))
854 exit-status success)
864 (make-directory (directory-file-name default-directory) t) 855 (make-directory (directory-file-name default-directory) t)
865 (apply 'call-process 856 (setq exit-status
866 (car command) 857 (apply 'call-process
867 nil 858 (car command)
868 nil 859 nil
869 nil 860 nil
870 (append (cdr command) (list archive name))) 861 nil
871 (insert-file-contents tmpfile) 862 (append (cdr command) (list archive name))))
872 (archive-delete-local tmpfile))) 863 (cond ((and (numberp exit-status) (= exit-status 0))
864 (if (not (file-exists-p tmpfile))
865 (ding (message "`%s': no such file or directory" tmpfile))
866 (insert-file-contents tmpfile)
867 (setq success t)))
868 ((numberp exit-status)
869 (ding
870 (message "`%s' exited with status %d" (car command) exit-status)))
871 ((stringp exit-status)
872 (ding (message "`%s' aborted: %s" (car command) exit-status)))
873 (t
874 (ding (message "`%s' failed" (car command)))))
875 (archive-delete-local tmpfile)
876 success))
873 877
874 (defun archive-extract-by-stdout (archive name command) 878 (defun archive-extract-by-stdout (archive name command)
875 (let ((binary-process-output t)) ; for Ms-Dos 879 ;; We need the coding system of the output of the extract program,
880 ;; including the EOL encoding, be decoded dynamically, since what
881 ;; the extract program outputs is the contents of some file.
882 (let ((coding-system-for-read (or coding-system-for-read 'undecided))
883 (inherit-process-coding-system t))
876 (apply 'call-process 884 (apply 'call-process
877 (car command) 885 (car command)
878 nil 886 nil
879 t 887 t
880 nil 888 nil
934 (funcall func buffer-file-name membuf name)) 942 (funcall func buffer-file-name membuf name))
935 (error "Adding a new member is not supported for this archive type")))) 943 (error "Adding a new member is not supported for this archive type"))))
936 ;; ------------------------------------------------------------------------- 944 ;; -------------------------------------------------------------------------
937 ;; Section: IO stuff 945 ;; Section: IO stuff
938 946
939 (defun archive-check-dos (&optional force)
940 "*Possibly handle a buffer with ^M^J terminated lines."
941 (save-restriction
942 (widen)
943 (save-excursion
944 (goto-char (point-min))
945 (setq archive-subfile-dos
946 (or force (not (search-forward-regexp "[^\r]\n" nil t))))
947 (if (boundp 'default-buffer-file-type)
948 (setq buffer-file-type (not archive-subfile-dos)))
949 (if archive-subfile-dos
950 (let ((modified (buffer-modified-p)))
951 (buffer-disable-undo (current-buffer))
952 (goto-char (point-min))
953 (while (search-forward "\r\n" nil t)
954 (replace-match "\n"))
955 (buffer-enable-undo)
956 (set-buffer-modified-p modified))))))
957
958 (defun archive-write-file-member () 947 (defun archive-write-file-member ()
959 (if archive-subfile-dos 948 (save-excursion
960 (save-restriction 949 (save-restriction
961 (widen) 950 (message "Updating archive...")
962 (save-excursion 951 (widen)
963 (goto-char (point-min)) 952 (let ((writer (save-excursion (set-buffer archive-superior-buffer)
964 ;; We don't want our ^M^J <--> ^J changes to show in the undo list 953 (archive-name "write-file-member")))
965 (let ((undo-list buffer-undo-list)) 954 (archive (save-excursion (set-buffer archive-superior-buffer)
966 (unwind-protect 955 (buffer-file-name))))
967 (progn 956 (if (fboundp writer)
968 (setq buffer-undo-list t) 957 (funcall writer archive archive-subfile-mode)
969 (while (search-forward "\n" nil t) 958 (archive-*-write-file-member archive
970 (replace-match "\r\n")) 959 archive-subfile-mode
971 (setq archive-subfile-dos nil) 960 (symbol-value writer))))
972 (if (boundp 'default-buffer-file-type) 961 (set-buffer-modified-p nil)
973 (setq buffer-file-type t)) 962 (message "Updating archive...done")
974 ;; OK, we're now have explicit ^M^Js -- save and re-unixfy 963 (set-buffer archive-superior-buffer)
975 (archive-write-file-member)) 964 (revert-buffer)
976 (progn 965 t)))
977 (archive-check-dos t)
978 (setq buffer-undo-list undo-list))))
979 t))
980 (save-excursion
981 (save-restriction
982 (message "Updating archive...")
983 (widen)
984 (let ((writer (save-excursion (set-buffer archive-superior-buffer)
985 (archive-name "write-file-member")))
986 (archive (save-excursion (set-buffer archive-superior-buffer)
987 (buffer-file-name))))
988 (if (fboundp writer)
989 (funcall writer archive archive-subfile-mode)
990 (archive-*-write-file-member archive
991 archive-subfile-mode
992 (symbol-value writer))))
993 (set-buffer-modified-p nil)
994 (message "Updating archive...done")
995 (set-buffer archive-superior-buffer)
996 (revert-buffer)
997 t))))
998 966
999 (defun archive-*-write-file-member (archive descr command) 967 (defun archive-*-write-file-member (archive descr command)
1000 (let* ((ename (aref descr 0)) 968 (let* ((ename (aref descr 0))
1001 (tmpfile (expand-file-name ename archive-tmpdir)) 969 (tmpfile (expand-file-name ename archive-tmpdir))
1002 (top (directory-file-name (file-name-as-directory archive-tmpdir))) 970 (top (directory-file-name (file-name-as-directory archive-tmpdir)))