Mercurial > emacs
comparison lisp/ange-ftp.el @ 22278:7a9f75f6e065
(ange-ftp-expand-file-name): Set default to
default-directory if nil. Check whether default starts with a
drive specifier on windows-nt, as well as name, and call real
function if so. Remove code to strip prefix before // or /~ since
`expand-file-name' itself no longer does that.
(ange-ftp-expand-dir): Use `grep-null-device' instead of
"/dev/null", which is incorrect on windows-nt.
(ange-ftp-file-name-all-completions): Fix root directory regexp for windows-nt.
(ange-ftp-start-process): On windows-nt, always send a "help foo"
command to ensure the ftp process produces some output, and force
the process to use raw-text-dos decoding.
(ange-ftp-canonize-filename): On windows-nt, strip drive specifier
from expanded remote name.
(ange-ftp-write-region): Allow binary transfer on windows-nt if
remote host type is unix. Ensure `last-coding-system-used' is
given an appropriate value, so that basic-save-buffer isn't
confused by the coding used with the ftp process.
(ange-ftp-insert-file-contents): Ditto.
(ange-ftp-copy-file-internal): Ditto.
(ange-ftp-real-expand-file-name): Use standard definition on windows-nt.
(ange-ftp-real-expand-file-name-actual): Remove obsolete function.
(ange-ftp-disable-netrc-security-check): Make default value be t on windows-nt.
(ange-ftp-start-process): Undo previous change.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 28 May 1998 05:14:17 +0000 |
parents | dfe597287db1 |
children | 4f8f06912912 |
comparison
equal
deleted
inserted
replaced
22277:cc85ea3f54cc | 22278:7a9f75f6e065 |
---|---|
719 (defcustom ange-ftp-netrc-filename "~/.netrc" | 719 (defcustom ange-ftp-netrc-filename "~/.netrc" |
720 "*File in .netrc format to search for passwords." | 720 "*File in .netrc format to search for passwords." |
721 :group 'ange-ftp | 721 :group 'ange-ftp |
722 :type 'file) | 722 :type 'file) |
723 | 723 |
724 (defcustom ange-ftp-disable-netrc-security-check nil | 724 (defcustom ange-ftp-disable-netrc-security-check (eq system-type 'windows-nt) |
725 "*If non-nil avoid checking permissions on the .netrc file." | 725 "*If non-nil avoid checking permissions on the .netrc file." |
726 :group 'ange-ftp | 726 :group 'ange-ftp |
727 :type 'boolean) | 727 :type 'boolean) |
728 | 728 |
729 (defcustom ange-ftp-default-user nil | 729 (defcustom ange-ftp-default-user nil |
1970 (goto-char (point-max)) | 1970 (goto-char (point-max)) |
1971 (set-marker (process-mark proc) (point))) | 1971 (set-marker (process-mark proc) (point))) |
1972 (process-kill-without-query proc) | 1972 (process-kill-without-query proc) |
1973 (set-process-sentinel proc (function ange-ftp-process-sentinel)) | 1973 (set-process-sentinel proc (function ange-ftp-process-sentinel)) |
1974 (set-process-filter proc (function ange-ftp-process-filter)) | 1974 (set-process-filter proc (function ange-ftp-process-filter)) |
1975 ;; wait for ftp startup message | 1975 ;; On Windows, the standard ftp client buffers its output (because |
1976 (if (not (eq system-type 'windows-nt)) | 1976 ;; stdout is a pipe handle) so the startup message may never appear: |
1977 (accept-process-output proc) | 1977 ;; `accept-process-output' at this point would hang indefinitely. |
1978 ;; On Windows, the standard ftp client behaves a little oddly, | 1978 ;; However, sending an innocuous command ("help foo") forces some |
1979 ;; initially buffering its output (because stdin/out are pipe | 1979 ;; output that will be ignored, which is just as good. Once we |
1980 ;; handles). As a result, the startup message doesn't appear | 1980 ;; start sending normal commands, the output no longer appears to be |
1981 ;; until enough output is generated to flush stdout, so a plain | 1981 ;; buffered, and everything works correctly. My guess is that the |
1982 ;; accept-process-output call at this point would hang | 1982 ;; output of interest is being sent to stderr which is not buffered. |
1983 ;; indefinitely. So if nothing appears within 2 seconds, we try | 1983 (when (eq system-type 'windows-nt) |
1984 ;; sending an innocuous command ("help foo") that forces some | 1984 ;; force ftp output to be treated as DOS text, otherwise the |
1985 ;; output. Curiously, once we start sending normal commands, the | 1985 ;; output of "help foo" confuses the EOL detection logic. |
1986 ;; output no longer appears to be buffered, and everything works | 1986 (set-process-coding-system proc 'raw-text-dos) |
1987 ;; correctly (or at least appears to!). | 1987 (process-send-string proc "help foo\n")) |
1988 (if (accept-process-output proc 2) | 1988 (accept-process-output proc) ;wait for ftp startup message |
1989 nil | |
1990 (process-send-string proc "help foo\n") | |
1991 (accept-process-output proc))) | |
1992 proc)) | 1989 proc)) |
1993 | 1990 |
1994 (put 'internal-ange-ftp-mode 'mode-class 'special) | 1991 (put 'internal-ange-ftp-mode 'mode-class 'special) |
1995 | 1992 |
1996 (defun internal-ange-ftp-mode () | 1993 (defun internal-ange-ftp-mode () |
2964 (not (eq host-type 'unix)) | 2961 (not (eq host-type 'unix)) |
2965 (let* ((ange-ftp-good-msgs (concat ange-ftp-expand-dir-regexp | 2962 (let* ((ange-ftp-good-msgs (concat ange-ftp-expand-dir-regexp |
2966 "\\|" | 2963 "\\|" |
2967 ange-ftp-good-msgs)) | 2964 ange-ftp-good-msgs)) |
2968 (result (ange-ftp-send-cmd host user | 2965 (result (ange-ftp-send-cmd host user |
2969 (list 'get dir "/dev/null") | 2966 (list 'get dir grep-null-device) |
2970 (format "expanding %s" dir))) | 2967 (format "expanding %s" dir))) |
2971 (line (cdr result))) | 2968 (line (cdr result))) |
2972 (setq res | 2969 (setq res |
2973 (if (string-match ange-ftp-expand-dir-regexp line) | 2970 (if (string-match ange-ftp-expand-dir-regexp line) |
2974 (substring line | 2971 (substring line |
3030 | 3027 |
3031 ;; If name starts with //, preserve that, for apollo system. | 3028 ;; If name starts with //, preserve that, for apollo system. |
3032 (if (not (string-match "^//" name)) | 3029 (if (not (string-match "^//" name)) |
3033 (progn | 3030 (progn |
3034 (setq name (ange-ftp-real-expand-file-name name)) | 3031 (setq name (ange-ftp-real-expand-file-name name)) |
3035 | 3032 ;; Strip off drive specifier added on windows-nt |
3033 (if (and (eq system-type 'windows-nt) | |
3034 (string-match "^[a-zA-Z]:" name)) | |
3035 (setq name (substring name 2))) | |
3036 (if (string-match "^//" name) | 3036 (if (string-match "^//" name) |
3037 (setq name (substring name 1))))) | 3037 (setq name (substring name 1))))) |
3038 | 3038 |
3039 ;; Now substitute the expanded name back into the overall filename. | 3039 ;; Now substitute the expanded name back into the overall filename. |
3040 (ange-ftp-replace-name-component n name)) | 3040 (ange-ftp-replace-name-component n name)) |
3047 (ange-ftp-real-file-name-directory n)))))) | 3047 (ange-ftp-real-file-name-directory n)))))) |
3048 | 3048 |
3049 (defun ange-ftp-expand-file-name (name &optional default) | 3049 (defun ange-ftp-expand-file-name (name &optional default) |
3050 "Documented as original." | 3050 "Documented as original." |
3051 (save-match-data | 3051 (save-match-data |
3052 (if (eq (string-to-char name) ?/) | 3052 (setq default (or default default-directory)) |
3053 (while (cond ((string-match "[^:]+//" name) ;don't upset Apollo users | |
3054 (setq name (substring name (1- (match-end 0))))) | |
3055 ((string-match "/~" name) | |
3056 (setq name (substring name (1- (match-end 0)))))))) | |
3057 (cond ((eq (string-to-char name) ?~) | 3053 (cond ((eq (string-to-char name) ?~) |
3058 (ange-ftp-real-expand-file-name name)) | 3054 (ange-ftp-real-expand-file-name name)) |
3059 ((eq (string-to-char name) ?/) | 3055 ((eq (string-to-char name) ?/) |
3060 (ange-ftp-canonize-filename name)) | 3056 (ange-ftp-canonize-filename name)) |
3061 ((and (eq system-type 'windows-nt) (string-match "^[a-zA-Z]:" name)) | 3057 ((and (eq system-type 'windows-nt) |
3062 name) ; when on local drive, return it as-is | 3058 (or (string-match "^[a-zA-Z]:" name) |
3059 (string-match "^[a-zA-Z]:" default))) | |
3060 (ange-ftp-real-expand-file-name name default)) | |
3063 ((zerop (length name)) | 3061 ((zerop (length name)) |
3064 (ange-ftp-canonize-filename (or default default-directory))) | 3062 (ange-ftp-canonize-filename default)) |
3065 ((ange-ftp-canonize-filename | 3063 ((ange-ftp-canonize-filename |
3066 (concat (file-name-as-directory (or default default-directory)) | 3064 (concat (file-name-as-directory default) name)))))) |
3067 name)))))) | |
3068 | 3065 |
3069 ;;; These are problems--they are currently not enabled. | 3066 ;;; These are problems--they are currently not enabled. |
3070 | 3067 |
3071 (defvar ange-ftp-file-name-as-directory-alist nil | 3068 (defvar ange-ftp-file-name-as-directory-alist nil |
3072 "Association list of \( TYPE \. FUNC \) pairs. | 3069 "Association list of \( TYPE \. FUNC \) pairs. |
3137 (temp (ange-ftp-make-tmp-name host)) | 3134 (temp (ange-ftp-make-tmp-name host)) |
3138 ;; What we REALLY need here is a way to determine if the mode | 3135 ;; What we REALLY need here is a way to determine if the mode |
3139 ;; of the transfer is irrelevant, i.e. we can use binary mode | 3136 ;; of the transfer is irrelevant, i.e. we can use binary mode |
3140 ;; regardless. Maybe a system-type to host-type lookup? | 3137 ;; regardless. Maybe a system-type to host-type lookup? |
3141 (binary (or (ange-ftp-binary-file filename) | 3138 (binary (or (ange-ftp-binary-file filename) |
3142 (and (not (eq system-type 'windows-nt)) | 3139 (eq (ange-ftp-host-type host user) 'unix))) |
3143 (eq (ange-ftp-host-type host user) 'unix)))) | |
3144 (cmd (if append 'append 'put)) | 3140 (cmd (if append 'append 'put)) |
3145 (abbr (ange-ftp-abbreviate-filename filename))) | 3141 (abbr (ange-ftp-abbreviate-filename filename)) |
3142 ;; we need to reset `last-coding-system-used' to its | |
3143 ;; value immediately after calling the real write-region, | |
3144 ;; so that `basic-save-buffer' doesn't see whatever value | |
3145 ;; might be used when communicating with the ftp process. | |
3146 (coding-system-used last-coding-system-used)) | |
3146 (unwind-protect | 3147 (unwind-protect |
3147 (progn | 3148 (progn |
3148 (let ((executing-kbd-macro t) | 3149 (let ((executing-kbd-macro t) |
3149 (filename (buffer-file-name)) | 3150 (filename (buffer-file-name)) |
3150 (mod-p (buffer-modified-p))) | 3151 (mod-p (buffer-modified-p))) |
3151 (unwind-protect | 3152 (unwind-protect |
3152 (ange-ftp-real-write-region start end temp nil visit) | 3153 (ange-ftp-real-write-region start end temp nil visit) |
3153 ;; cleanup forms | 3154 ;; cleanup forms |
3154 (setq buffer-file-name filename) | 3155 (setq buffer-file-name filename) |
3155 (set-buffer-modified-p mod-p))) | 3156 (set-buffer-modified-p mod-p))) |
3157 ;; save value used by the real write-region | |
3158 (setq coding-system-used last-coding-system-used) | |
3156 (if binary | 3159 (if binary |
3157 (ange-ftp-set-binary-mode host user)) | 3160 (ange-ftp-set-binary-mode host user)) |
3158 | 3161 |
3159 ;; tell the process filter what size the transfer will be. | 3162 ;; tell the process filter what size the transfer will be. |
3160 (let ((attr (file-attributes temp))) | 3163 (let ((attr (file-attributes temp))) |
3178 (progn | 3181 (progn |
3179 (set-visited-file-modtime '(0 0)) | 3182 (set-visited-file-modtime '(0 0)) |
3180 (ange-ftp-set-buffer-mode) | 3183 (ange-ftp-set-buffer-mode) |
3181 (setq buffer-file-name filename) | 3184 (setq buffer-file-name filename) |
3182 (set-buffer-modified-p nil))) | 3185 (set-buffer-modified-p nil))) |
3186 ;; ensure `last-coding-system-used' has an appropriate value | |
3187 (setq last-coding-system-used coding-system-used) | |
3183 (ange-ftp-message "Wrote %s" abbr) | 3188 (ange-ftp-message "Wrote %s" abbr) |
3184 (ange-ftp-add-file-entry filename)) | 3189 (ange-ftp-add-file-entry filename)) |
3185 (ange-ftp-real-write-region start end filename append visit)))) | 3190 (ange-ftp-real-write-region start end filename append visit)))) |
3186 | 3191 |
3187 (defun ange-ftp-insert-file-contents (filename &optional visit beg end replace) | 3192 (defun ange-ftp-insert-file-contents (filename &optional visit beg end replace) |
3201 (let* ((host (nth 0 parsed)) | 3206 (let* ((host (nth 0 parsed)) |
3202 (user (nth 1 parsed)) | 3207 (user (nth 1 parsed)) |
3203 (name (ange-ftp-quote-string (nth 2 parsed))) | 3208 (name (ange-ftp-quote-string (nth 2 parsed))) |
3204 (temp (ange-ftp-make-tmp-name host)) | 3209 (temp (ange-ftp-make-tmp-name host)) |
3205 (binary (or (ange-ftp-binary-file filename) | 3210 (binary (or (ange-ftp-binary-file filename) |
3206 (and (not (eq system-type 'windows-nt)) | 3211 (eq (ange-ftp-host-type host user) 'unix))) |
3207 (eq (ange-ftp-host-type host user) 'unix)))) | |
3208 (abbr (ange-ftp-abbreviate-filename filename)) | 3212 (abbr (ange-ftp-abbreviate-filename filename)) |
3209 size) | 3213 size) |
3210 (unwind-protect | 3214 (unwind-protect |
3211 (progn | 3215 (progn |
3212 (if binary | 3216 (if binary |
3487 (t-user (and t-parsed (nth 1 t-parsed))) | 3491 (t-user (and t-parsed (nth 1 t-parsed))) |
3488 (t-name (and t-parsed (ange-ftp-quote-string (nth 2 t-parsed)))) | 3492 (t-name (and t-parsed (ange-ftp-quote-string (nth 2 t-parsed)))) |
3489 (t-abbr (ange-ftp-abbreviate-filename newname filename)) | 3493 (t-abbr (ange-ftp-abbreviate-filename newname filename)) |
3490 (binary (or (ange-ftp-binary-file filename) | 3494 (binary (or (ange-ftp-binary-file filename) |
3491 (ange-ftp-binary-file newname) | 3495 (ange-ftp-binary-file newname) |
3492 (and (not (eq system-type 'windows-nt)) | 3496 (and (eq (ange-ftp-host-type f-host f-user) 'unix) |
3493 (eq (ange-ftp-host-type f-host f-user) 'unix) | |
3494 (eq (ange-ftp-host-type t-host t-user) 'unix)))) | 3497 (eq (ange-ftp-host-type t-host t-user) 'unix)))) |
3495 temp1 | 3498 temp1 |
3496 temp2) | 3499 temp2) |
3497 | 3500 |
3498 ;; check to see if we can overwrite | 3501 ;; check to see if we can overwrite |
3777 (concat file "/") | 3780 (concat file "/") |
3778 file)))) | 3781 file)))) |
3779 completions))) | 3782 completions))) |
3780 | 3783 |
3781 (if (or (and (eq system-type 'windows-nt) | 3784 (if (or (and (eq system-type 'windows-nt) |
3782 (string-match "[^a-zA-Z]?[a-zA-Z]:[/\]" ange-ftp-this-dir)) | 3785 (string-match "^[a-zA-Z]:[/\]$" ange-ftp-this-dir)) |
3783 (string-equal "/" ange-ftp-this-dir)) | 3786 (string-equal "/" ange-ftp-this-dir)) |
3784 (nconc (all-completions file (ange-ftp-generate-root-prefixes)) | 3787 (nconc (all-completions file (ange-ftp-generate-root-prefixes)) |
3785 (ange-ftp-real-file-name-all-completions file | 3788 (ange-ftp-real-file-name-all-completions file |
3786 ange-ftp-this-dir)) | 3789 ange-ftp-this-dir)) |
3787 (ange-ftp-real-file-name-all-completions file ange-ftp-this-dir))))) | 3790 (ange-ftp-real-file-name-all-completions file ange-ftp-this-dir))))) |
4081 (or (assoc "^/[^/:]*[^/:.]:" file-name-handler-alist) | 4084 (or (assoc "^/[^/:]*[^/:.]:" file-name-handler-alist) |
4082 (setq file-name-handler-alist | 4085 (setq file-name-handler-alist |
4083 (cons '("^/[^/:]*[^/:.]:" . ange-ftp-hook-function) | 4086 (cons '("^/[^/:]*[^/:.]:" . ange-ftp-hook-function) |
4084 file-name-handler-alist))) | 4087 file-name-handler-alist))) |
4085 | 4088 |
4086 ;;; Real ange-ftp file names prefixed with a drive letter. | |
4087 ;;;###autoload | |
4088 (and (memq system-type '(ms-dos windows-nt)) | |
4089 (or (assoc "^[a-zA-Z]:/[^/:]*[^/:.]:" file-name-handler-alist) | |
4090 (setq file-name-handler-alist | |
4091 (cons '("^[a-zA-Z]:/[^/:]*[^/:.]:" . ange-ftp-hook-function) | |
4092 file-name-handler-alist)))) | |
4093 | |
4094 ;;; This regexp recognizes and absolute filenames with only one component, | 4089 ;;; This regexp recognizes and absolute filenames with only one component, |
4095 ;;; for the sake of hostname completion. | 4090 ;;; for the sake of hostname completion. |
4096 ;;;###autoload | 4091 ;;;###autoload |
4097 (or (assoc "^/[^/:]*\\'" file-name-handler-alist) | 4092 (or (assoc "^/[^/:]*\\'" file-name-handler-alist) |
4098 (setq file-name-handler-alist | 4093 (setq file-name-handler-alist |
4183 (ange-ftp-run-real-handler 'file-name-nondirectory args)) | 4178 (ange-ftp-run-real-handler 'file-name-nondirectory args)) |
4184 (defun ange-ftp-real-file-name-as-directory (&rest args) | 4179 (defun ange-ftp-real-file-name-as-directory (&rest args) |
4185 (ange-ftp-run-real-handler 'file-name-as-directory args)) | 4180 (ange-ftp-run-real-handler 'file-name-as-directory args)) |
4186 (defun ange-ftp-real-directory-file-name (&rest args) | 4181 (defun ange-ftp-real-directory-file-name (&rest args) |
4187 (ange-ftp-run-real-handler 'directory-file-name args)) | 4182 (ange-ftp-run-real-handler 'directory-file-name args)) |
4188 (or (and (eq system-type 'windows-nt) | |
4189 ;; Windows handler for [A-Z]: drive name on local disks | |
4190 (defun ange-ftp-real-expand-file-name (&rest args) | |
4191 (ange-ftp-run-real-handler 'ange-ftp-real-expand-file-name-actual args))) | |
4192 (defun ange-ftp-real-expand-file-name (&rest args) | 4183 (defun ange-ftp-real-expand-file-name (&rest args) |
4193 (ange-ftp-run-real-handler 'expand-file-name args))) | 4184 (ange-ftp-run-real-handler 'expand-file-name args)) |
4194 (defun ange-ftp-real-make-directory (&rest args) | 4185 (defun ange-ftp-real-make-directory (&rest args) |
4195 (ange-ftp-run-real-handler 'make-directory args)) | 4186 (ange-ftp-run-real-handler 'make-directory args)) |
4196 (defun ange-ftp-real-delete-directory (&rest args) | 4187 (defun ange-ftp-real-delete-directory (&rest args) |
4197 (ange-ftp-run-real-handler 'delete-directory args)) | 4188 (ange-ftp-run-real-handler 'delete-directory args)) |
4198 (defun ange-ftp-real-insert-file-contents (&rest args) | 4189 (defun ange-ftp-real-insert-file-contents (&rest args) |
5681 ;;(or (assq 'cms ange-ftp-dired-get-filename-alist) | 5672 ;;(or (assq 'cms ange-ftp-dired-get-filename-alist) |
5682 ;; (setq ange-ftp-dired-get-filename-alist | 5673 ;; (setq ange-ftp-dired-get-filename-alist |
5683 ;; (cons '(cms . ange-ftp-dired-cms-get-filename) | 5674 ;; (cons '(cms . ange-ftp-dired-cms-get-filename) |
5684 ;; ange-ftp-dired-get-filename-alist))) | 5675 ;; ange-ftp-dired-get-filename-alist))) |
5685 | 5676 |
5686 ;; | |
5687 (and (eq system-type 'windows-nt) | |
5688 (setq ange-ftp-disable-netrc-security-check t)) | |
5689 | |
5690 ;; If a drive letter has been added, remote it. Otherwise, if the drive | |
5691 ;; letter existed before, leave it. | |
5692 (defun ange-ftp-real-expand-file-name-actual (&rest args) | |
5693 (let (old-name new-name final drive-letter) | |
5694 (setq old-name (car args)) | |
5695 (setq new-name (ange-ftp-run-real-handler 'expand-file-name args)) | |
5696 (setq drive-letter (substring new-name 0 2)) | |
5697 ;; I'd like to distill the following lines into one (if) statement | |
5698 ;; removing the need for the temp final variable | |
5699 (setq final new-name) | |
5700 (if (not (equal (substring old-name 0 1) "~")) | |
5701 (if (or (< (length old-name) 2) | |
5702 (not (string-match "/[a-zA-Z]:" old-name))) | |
5703 (setq final (substring new-name 2)))) | |
5704 final)) | |
5705 | |
5706 | |
5707 ;;;; ------------------------------------------------------------ | 5677 ;;;; ------------------------------------------------------------ |
5708 ;;;; Finally provide package. | 5678 ;;;; Finally provide package. |
5709 ;;;; ------------------------------------------------------------ | 5679 ;;;; ------------------------------------------------------------ |
5710 | 5680 |
5711 (provide 'ange-ftp) | 5681 (provide 'ange-ftp) |