From 8ac08792a71e07bce0e62d93bed80553fbe95a40 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Wed, 4 Mar 2015 11:02:36 +0100 Subject: [PATCH] Sync with Tramp upstream. * net/tramp-cache.el (tramp-dump-connection-properties): Use `with-temp-file'. * net/tramp-sh.el (tramp-perl-file-attributes) (tramp-perl-directory-files-and-attributes): Escape apostrophs in file names. (tramp-do-file-attributes-with-stat): Quote file name. (tramp-sh-handle-directory-files-and-attributes): Fall back to `tramp-handle-directory-files-and-attributes' in case of problems. (tramp-do-directory-files-and-attributes-with-stat) (tramp-sh-handle-file-name-all-completions) (tramp-sh-handle-delete-directory) (tramp-sh-handle-expand-file-name, tramp-sh-handle-process-file): Normalize use of "cd". (tramp-do-directory-files-and-attributes-with-stat): Use the `quoting-style' arg of `ls' if possible. Make it also working for file names with apostrophs. (tramp-sh-handle-file-name-all-completions): Use arguments of `ls' in proper order. (tramp-do-copy-or-rename-file-via-buffer) (tramp-sh-handle-file-local-copy): Use `with-temp-file'. (tramp-get-remote-locale): Accept also \r in output. (tramp-get-ls-command-with-quoting-style): New defun. (tramp-get-inline-coding): Set `default-directory' to a local directory. Sporadically, `call-process-region' does not handle a remote default directory properly. * net/tramp.el (tramp): Add :link property. (tramp-login-prompt-regexp): Allow also "user", as required by Fritz!Box telnet. (tramp-autoload-file-name-handler): Use "/". (tramp-handle-unhandled-file-name-directory): Return nil when required by the spec. * net/trampver.el: Update release number. --- lisp/ChangeLog | 38 ++++++++ lisp/net/tramp-cache.el | 6 +- lisp/net/tramp-sh.el | 186 ++++++++++++++++++++++------------------ lisp/net/tramp.el | 14 +-- lisp/net/trampver.el | 4 +- 5 files changed, 152 insertions(+), 96 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 60e2b50e5c4..8d7360f899c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,41 @@ +2015-03-04 Michael Albinus + + * net/tramp.el (tramp): Add :link property. + (tramp-login-prompt-regexp): Allow also "user", as required by + Fritz!Box telnet. + (tramp-autoload-file-name-handler): Use "/". + (tramp-handle-unhandled-file-name-directory): Return nil when + required by the spec. + + * net/tramp-cache.el (tramp-dump-connection-properties): + Use `with-temp-file'. + + * net/tramp-sh.el (tramp-perl-file-attributes) + (tramp-perl-directory-files-and-attributes): Escape apostrophs in + file names. + (tramp-do-file-attributes-with-stat): Quote file name. + (tramp-sh-handle-directory-files-and-attributes): Fall back to + `tramp-handle-directory-files-and-attributes' in case of problems. + (tramp-do-directory-files-and-attributes-with-stat) + (tramp-sh-handle-file-name-all-completions) + (tramp-sh-handle-delete-directory) + (tramp-sh-handle-expand-file-name, tramp-sh-handle-process-file): + Normalize use of "cd". + (tramp-do-directory-files-and-attributes-with-stat): Use the + `quoting-style' arg of `ls' if possible. Make it also working for + file names with apostrophs. + (tramp-sh-handle-file-name-all-completions): Use arguments of `ls' + in proper order. + (tramp-do-copy-or-rename-file-via-buffer) + (tramp-sh-handle-file-local-copy): Use `with-temp-file'. + (tramp-get-remote-locale): Accept also \r in output. + (tramp-get-ls-command-with-quoting-style): New defun. + (tramp-get-inline-coding): Set `default-directory' to a local + directory. Sporadically, `call-process-region' does not handle a + remote default directory properly. + + * net/trampver.el: Update release number. + 2015-03-03 Agustín Martín Domingo * textmodes/ispell.el (ispell-aspell-find-dictionary): Make sure diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index fb9d5e84c94..1e24ea53f43 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -362,7 +362,7 @@ KEY identifies the connection, it is either a process or a vector." (remhash key cache))) cache) ;; Dump it. - (with-temp-buffer + (with-temp-file tramp-persistency-file-name (insert ";; -*- emacs-lisp -*-" ;; `time-stamp-string' might not exist in all (X)Emacs flavors. @@ -376,9 +376,7 @@ KEY identifies the connection, it is either a process or a vector." ";; Tramp connection history. Don't change this file.\n" ";; You can delete it, forcing Tramp to reapply the checks.\n\n" (with-output-to-string - (pp (read (format "(%s)" (tramp-cache-print cache)))))) - (write-region - (point-min) (point-max) tramp-persistency-file-name)))))) + (pp (read (format "(%s)" (tramp-cache-print cache))))))))))) (unless noninteractive (add-hook 'kill-emacs-hook 'tramp-dump-connection-properties)) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index f3fdb63bb9e..580c5d08ecd 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -631,6 +631,7 @@ if (!@stat) { if (($stat[2] & 0170000) == 0120000) { $type = readlink($ARGV[0]); + $type =~ s/\"/\\\\\"/g; $type = \"\\\"$type\\\"\"; } elsif (($stat[2] & 0170000) == 040000) @@ -680,6 +681,7 @@ for($i = 0; $i < $n; $i++) if (($stat[2] & 0170000) == 0120000) { $type = readlink($filename); + $type =~ s/\"/\\\\\"/g; $type = \"\\\"$type\\\"\"; } elsif (($stat[2] & 0170000) == 040000) @@ -692,6 +694,7 @@ for($i = 0; $i < $n; $i++) }; $uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\"; $gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\"; + $filename =~ s/\"/\\\\\"/g; printf( \"(\\\"%%s\\\" %%s %%u %%s %%s (%%u %%u) (%%u %%u) (%%u %%u) %%u.0 %%u t (%%u . %%u) (%%u . %%u))\\n\", $filename, @@ -1250,7 +1253,7 @@ target of the symlink differ." (format ;; On Opsware, pdksh (which is the true name of ksh there) doesn't ;; parse correctly the sequence "((". Therefore, we add a space. - "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' %s || echo nil)" + "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' \"%s\" || echo nil)" (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) @@ -1626,45 +1629,44 @@ be non-negative integers." (defun tramp-sh-handle-directory-files-and-attributes (directory &optional full match nosort id-format) "Like `directory-files-and-attributes' for Tramp files." - (if (with-parsed-tramp-file-name directory nil - (not (or (tramp-get-remote-stat v) (tramp-get-remote-perl v)))) - (tramp-handle-directory-files-and-attributes - directory full match nosort id-format) - - ;; Do it directly. - (unless id-format (setq id-format 'integer)) - (when (file-directory-p directory) - (setq directory (expand-file-name directory)) - (let* ((temp - (copy-tree - (with-parsed-tramp-file-name directory nil - (with-tramp-file-property - v localname - (format "directory-files-and-attributes-%s" id-format) - (save-excursion - (mapcar - (lambda (x) - (cons (car x) - (tramp-convert-file-attributes v (cdr x)))) - (cond - ((tramp-get-remote-stat v) - (tramp-do-directory-files-and-attributes-with-stat - v localname id-format)) - ((tramp-get-remote-perl v) - (tramp-do-directory-files-and-attributes-with-perl - v localname id-format))))))))) - result item) - - (while temp - (setq item (pop temp)) - (when (or (null match) (string-match match (car item))) - (when full - (setcar item (expand-file-name (car item) directory))) - (push item result))) - - (if nosort - result - (sort result (lambda (x y) (string< (car x) (car y))))))))) + (unless id-format (setq id-format 'integer)) + (when (file-directory-p directory) + (setq directory (expand-file-name directory)) + (let* ((temp + (copy-tree + (with-parsed-tramp-file-name directory nil + (with-tramp-file-property + v localname + (format "directory-files-and-attributes-%s" id-format) + (save-excursion + (mapcar + (lambda (x) + (cons (car x) + (tramp-convert-file-attributes v (cdr x)))) + (or + (cond + ((tramp-get-remote-stat v) + (tramp-do-directory-files-and-attributes-with-stat + v localname id-format)) + ((tramp-get-remote-perl v) + (tramp-do-directory-files-and-attributes-with-perl + v localname id-format)) + (t nil))))))))) + result item) + + (while temp + (setq item (pop temp)) + (when (or (null match) (string-match match (car item))) + (when full + (setcar item (expand-file-name (car item) directory))) + (push item result))) + + (or (if nosort + result + (sort result (lambda (x y) (string< (car x) (car y))))) + ;; The scripts could fail, for example with huge file size. + (tramp-handle-directory-files-and-attributes + directory full match nosort id-format))))) (defun tramp-do-directory-files-and-attributes-with-perl (vec localname &optional id-format) @@ -1692,16 +1694,22 @@ be non-negative integers." ;; We must care about file names with spaces, or starting with ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, ;; but it does not work on all remote systems. Therefore, we - ;; quote the file names via sed. - "cd %s; echo \"(\"; (%s -a | sed -e s/\\$/\\\"/g -e s/^/\\\"/g | " + ;; use \000 as file separator. + ;; Apostrophs in the stat output are masked as \037 character, in + ;; order to make a proper shell escape of them in file names. + "cd %s && echo \"(\"; (%s %s -a | " "xargs %s -c " - "'(\"%%n\" (\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)'" - " 2>/dev/null); echo \")\"") + "'(\037%%n\037 (\037%%N\037) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \037%%A\037 t %%ie0 -1)'" + " -- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\037/\"/g'); echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) + ;; On systems which have no quotings style, file names with + ;; special characters could fail. + (if (tramp-get-ls-command-with-quoting-style vec) + "--quoting-style=shell" "") (tramp-get-remote-stat vec) - (if (eq id-format 'integer) "%ue0" "\"%U\"") - (if (eq id-format 'integer) "%ge0" "\"%G\"")))) + (if (eq id-format 'integer) "%ue0" "\037%U\037") + (if (eq id-format 'integer) "%ge0" "\037%G\037")))) ;; This function should return "foo/" for directories and "bar" for ;; files. @@ -1772,7 +1780,7 @@ be non-negative integers." 1 0))) (format (concat - "(\\cd %s 2>&1 && (%s %s -a 2>/dev/null" + "(cd %s 2>&1 && (%s -a %s 2>/dev/null" ;; `ls' with wildcard might fail with `Argument ;; list too long' error in some corner cases; if ;; `ls' fails after `cd' succeeded, chances are @@ -1796,7 +1804,7 @@ be non-negative integers." ;; sub-directories. (if (zerop (length filename)) "." - (concat (tramp-shell-quote-argument filename) "* -d")) + (format "-d %s*" (tramp-shell-quote-argument filename))) (tramp-get-ls-command v) (tramp-get-test-command v)))) @@ -2078,23 +2086,20 @@ file names." First arg OP is either `copy' or `rename' and indicates the operation. FILENAME is the source file, NEWNAME the target file. KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." - (with-temp-buffer - ;; We must disable multibyte, because binary data shall not be - ;; converted. We remove `tramp-file-name-handler' from - ;; `inhibit-file-name-handlers'; otherwise the file name handler - ;; for `insert-file-contents' might be deactivated in some corner - ;; cases. - (set-buffer-multibyte nil) - (let ((coding-system-for-read 'binary) - (jka-compr-inhibit t) - (inhibit-file-name-handlers - (remq 'tramp-file-name-handler inhibit-file-name-handlers))) - (insert-file-contents-literally filename)) - ;; We don't want the target file to be compressed, so we let-bind - ;; `jka-compr-inhibit' to t. - (let ((coding-system-for-write 'binary) - (jka-compr-inhibit t)) - (write-region (point-min) (point-max) newname nil 'no-message))) + ;; We must disable multibyte, because binary data shall not be + ;; converted. We don't want the target file to be compressed, so we + ;; let-bind `jka-compr-inhibit' to t. + ;; We remove `tramp-file-name-handler' from + ;; `inhibit-file-name-handlers'; otherwise the file name handler for + ;; `insert-file-contents' might be deactivated in some corner cases. + (let ((coding-system-for-read 'binary) + (coding-system-for-write 'binary) + (jka-compr-inhibit t) + (inhibit-file-name-handlers + (remq 'tramp-file-name-handler inhibit-file-name-handlers))) + (with-temp-file newname + (set-buffer-multibyte nil) + (insert-file-contents-literally filename))) ;; KEEP-DATE handling. (when keep-date (set-file-times newname (nth 5 (file-attributes filename)))) ;; Set the mode. @@ -2541,7 +2546,7 @@ The method used must be an out-of-band method." (tramp-flush-file-property v (file-name-directory localname)) (tramp-flush-directory-property v localname) (tramp-barf-unless-okay - v (format "%s %s" + v (format "cd / && %s %s" (if recursive "rm -rf" "rmdir") (tramp-shell-quote-argument localname)) "Couldn't delete %s" directory))) @@ -2799,7 +2804,7 @@ the result will be a local, non-Tramp, file name." (setq uname (with-tramp-connection-property v uname (tramp-send-command - v (format "cd %s; pwd" (tramp-shell-quote-argument uname))) + v (format "cd %s && pwd" (tramp-shell-quote-argument uname))) (with-current-buffer (tramp-get-buffer v) (goto-char (point-min)) (buffer-substring (point) (point-at-eol))))) @@ -3037,7 +3042,7 @@ the result will be a local, non-Tramp, file name." (unwind-protect (setq ret (if (tramp-send-command-and-check - v (format "\\cd %s; %s" + v (format "cd %s && %s" (tramp-shell-quote-argument localname) command) t t) @@ -3116,17 +3121,14 @@ the result will be a local, non-Tramp, file name." ;; If local decoding is a function, we call it. ;; We must disable multibyte, because ;; `uudecode-decode-region' doesn't handle it - ;; correctly. - (with-temp-buffer - (set-buffer-multibyte nil) - (insert-buffer-substring (tramp-get-buffer v)) - (funcall loc-dec (point-min) (point-max)) - ;; Unset `file-name-handler-alist'. Otherwise, - ;; epa-file gets confused. - (let (file-name-handler-alist - (coding-system-for-write 'binary)) - (write-region - (point-min) (point-max) tmpfile nil 'no-message))) + ;; correctly. Unset `file-name-handler-alist'. + ;; Otherwise, epa-file gets confused. + (let (file-name-handler-alist + (coding-system-for-write 'binary)) + (with-temp-file tmpfile + (set-buffer-multibyte nil) + (insert-buffer-substring (tramp-get-buffer v)) + (funcall loc-dec (point-min) (point-max)))) ;; If tramp-decoding-function is not defined for this ;; method, we invoke tramp-decoding-command instead. @@ -3708,8 +3710,8 @@ Only send the definition if it has not already been done." (tramp-error vec 'file-error "No Perl available on remote host")) (tramp-barf-unless-okay vec - (format "%s () {\n%s\n}" name - (format script (tramp-get-remote-perl vec))) + (format "%s () {\n%s\n}" + name (format script (tramp-get-remote-perl vec))) "Script %s sending failed" name) (tramp-set-connection-property (tramp-get-connection-process vec) "scripts" (cons name scripts)))))) @@ -5157,7 +5159,8 @@ Return ATTR." (with-current-buffer (tramp-get-connection-buffer vec) (while candidates (goto-char (point-min)) - (if (string-match (concat "^" (car candidates) "$") (buffer-string)) + (if (string-match (format "^%s\r?$" (regexp-quote (car candidates))) + (buffer-string)) (setq locale (car candidates) candidates nil) (setq candidates (cdr candidates))))) @@ -5199,6 +5202,17 @@ Return ATTR." (tramp-send-command-and-check vec (format "%s --dired -al /dev/null" (tramp-get-ls-command vec)))))) +(defun tramp-get-ls-command-with-quoting-style (vec) + (save-match-data + (with-tramp-connection-property vec "ls-quoting-style" + (tramp-message vec 5 "Checking, whether `ls --quoting-style=shell' works") + ;; Some "ls" versions are sensible wrt the order of arguments, + ;; they fail when "-al" is after the "--dired" argument (for + ;; example on FreeBSD). + (tramp-send-command-and-check + vec (format "%s --quoting-style=shell -al /dev/null" + (tramp-get-ls-command vec)))))) + (defun tramp-get-test-command (vec) (with-tramp-connection-property vec "test" (tramp-message vec 5 "Finding a suitable `test' command") @@ -5486,14 +5500,18 @@ function cell is returned to be applied on a buffer." `(lambda (beg end) (,coding beg end) (let ((coding-system-for-write 'binary) - (coding-system-for-read 'binary)) + (coding-system-for-read 'binary) + (default-directory + (tramp-compat-temporary-file-directory))) (apply 'call-process-region (point-min) (point-max) (car (split-string ,compress)) t t nil (cdr (split-string ,compress))))) `(lambda (beg end) (let ((coding-system-for-write 'binary) - (coding-system-for-read 'binary)) + (coding-system-for-read 'binary) + (default-directory + (tramp-compat-temporary-file-directory))) (apply 'call-process-region beg end (car (split-string ,compress)) t t nil diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index a03affa5eeb..953525f37e4 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -73,6 +73,7 @@ "Edit remote files with a combination of ssh, scp, etc." :group 'files :group 'comm + :link '(custom-manual "(tramp)Top") :version "22.1") ;; Maybe we need once a real Tramp mode, with key bindings etc. @@ -557,7 +558,7 @@ if you need to change this." :type 'string) (defcustom tramp-login-prompt-regexp - ".*ogin\\( .*\\)?: *" + ".*\\(user\\|login\\)\\( .*\\)?: *" "Regexp matching login-like prompts. The regexp should match at end of buffer. @@ -2263,7 +2264,7 @@ Falls back to normal file name handler if no Tramp file name handler exists." "Load Tramp file name handler, and perform OPERATION." ;; Avoid recursive loading of tramp.el. `temporary-file-directory' ;; does not exist in XEmacs, so we must use something else. - (let ((default-directory (or (symbol-value 'temporary-file-directory) "/"))) + (let ((default-directory "/")) (load "tramp" nil t)) (apply operation args))) @@ -3352,10 +3353,11 @@ User is always nil." (defun tramp-handle-unhandled-file-name-directory (_filename) "Like `unhandled-file-name-directory' for Tramp files." - ;; With Emacs 23, we could simply return `nil'. But we must keep it - ;; for backward compatibility. "~/" cannot be returned, because - ;; there might be machines without a HOME directory (like hydra). - "/") + ;; Starting with Emacs 23, we must simply return `nil'. But we must + ;; keep backward compatibility, also with XEmacs. "~/" cannot be + ;; returned, because there might be machines without a HOME + ;; directory (like hydra). + (and (< emacs-major-version 23) "/")) (defun tramp-handle-set-visited-file-modtime (&optional time-list) "Like `set-visited-file-modtime' for Tramp files." diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 70092d21207..226ec9f194a 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -31,7 +31,7 @@ ;; should be changed only there. ;;;###tramp-autoload -(defconst tramp-version "2.2.11-24.5" +(defconst tramp-version "2.2.12-pre" "This version of Tramp.") ;;;###tramp-autoload @@ -44,7 +44,7 @@ (= emacs-major-version 21) (>= emacs-minor-version 4))) "ok" - (format "Tramp 2.2.11-24.5 is not fit for %s" + (format "Tramp 2.2.12-pre is not fit for %s" (when (string-match "^.*$" (emacs-version)) (match-string 0 (emacs-version))))))) (unless (string-match "\\`ok\\'" x) (error "%s" x))) -- 2.39.2