X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e57f766d3c97162258ec24b2b4986cdc0e98d352..59ff39dca6e5b85b03ec5453d256382e06771ab3:/lisp/net/tramp-sh.el diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 80a256c8d3..7f7558e93b 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -40,6 +40,7 @@ (defvar vc-git-program) (defvar vc-hg-program) +;;;###tramp-autoload (defcustom tramp-inline-compress-start-size 4096 "The minimum size of compressing where inline transfer. When inline transfer, compress transferred data of file @@ -48,6 +49,7 @@ If it is nil, no compression at all will be applied." :group 'tramp :type '(choice (const nil) integer)) +;;;###tramp-autoload (defcustom tramp-copy-size-limit 10240 "The maximum file size where inline copying is preferred over an \ out-of-the-band copy. @@ -65,19 +67,21 @@ files conditionalize this setup based on the TERM environment variable." :type 'string) ;;;###tramp-autoload -(defcustom tramp-histfile-override "/dev/null" +(defcustom tramp-histfile-override ".tramp_history" "When invoking a shell, override the HISTFILE with this value. -By default, the HISTFILE is set to the \"/dev/null\" value, which -is special on Unix systems and indicates the shell history should -not be logged (this avoids clutter due to Tramp commands). - -If you set this variable to nil, however, the *override* is -disabled, so the history will go to the default storage -location, e.g. \"$HOME/.sh_history\"." +When setting to a string, it redirects the shell history to that +file. Be careful when setting to \"/dev/null\"; this might +result in undesired results when using \"bash\" as shell. + +The value t, the default value, unsets any setting of HISTFILE, +and sets both HISTFILESIZE and HISTSIZE to 0. If you set this +variable to nil, however, the *override* is disabled, so the +history will go to the default storage location, +e.g. \"$HOME/.sh_history\"." :group 'tramp :version "25.1" :type '(choice (const :tag "Do not override HISTFILE" nil) - (const :tag "Empty the history (/dev/null)" "/dev/null") + (const :tag "Unset HISTFILE" t) (string :tag "Redirect to a file"))) ;;;###tramp-autoload @@ -103,6 +107,27 @@ detected as prompt when being sent on echoing hosts, therefore.") (defconst tramp-end-of-heredoc (md5 tramp-end-of-output) "String used to recognize end of heredoc strings.") +;;;###tramp-autoload +(defcustom tramp-use-ssh-controlmaster-options t + "Whether to use `tramp-ssh-controlmaster-options'." + :group 'tramp + :version "24.4" + :type 'boolean) + +(defvar tramp-ssh-controlmaster-options nil + "Which ssh Control* arguments to use. + +If it is a string, it should have the form +\"-o ControlMaster=auto -o ControlPath='tramp.%%r@%%h:%%p' +-o ControlPersist=no\". Percent characters in the ControlPath +spec must be doubled, because the string is used as format string. + +Otherwise, it will be auto-detected by Tramp, if +`tramp-use-ssh-controlmaster-options' is non-nil. The value +depends on the installed local ssh version. + +The string is used in `tramp-methods'.") + ;; Initialize `tramp-methods' with the supported methods. ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -110,6 +135,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "rsh") (tramp-login-args (("%h") ("-l" "%u"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "rcp") (tramp-copy-args (("-p" "%k") ("-r"))) @@ -121,6 +147,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "remsh") (tramp-login-args (("%h") ("-l" "%u"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "rcp") (tramp-copy-args (("-p" "%k"))) @@ -133,6 +160,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") ("-q") ("-r") ("%c"))) @@ -150,6 +178,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh"))) (tramp-async-args (("-q"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "scp") (tramp-copy-args (("-P" "%p") ("-p" "%k") @@ -168,6 +197,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "rsync") (tramp-copy-args (("-t" "%k") ("-r"))) @@ -181,6 +211,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "rsh") (tramp-login-args (("%h") ("-l" "%u"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -188,6 +219,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "remsh") (tramp-login-args (("%h") ("-l" "%u"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -197,6 +229,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ("-e" "none") ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") @@ -210,6 +243,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh"))) (tramp-async-args (("-q"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") ("-o" "UserKnownHostsFile=/dev/null") @@ -221,6 +255,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "telnet") (tramp-login-args (("%h") ("%p") ("2>/dev/null"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-default-port 23))) ;;;###tramp-autoload @@ -229,6 +264,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "telnet") (tramp-login-args (("%h") ("%p") ("2>/dev/null"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "nc") ;; We use "-v" for better error tracking. @@ -237,7 +273,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ;; We use "-p" as required for newer busyboxes. For older ;; busybox/nc versions, the value must be (("-l") ("%r")). This ;; can be achieved by tweaking `tramp-connection-properties'. - (tramp-remote-copy-args (("-l") ("-p" "%r"))) + (tramp-remote-copy-args (("-l") ("-p" "%r") ("2>/dev/null"))) (tramp-default-port 23))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -245,6 +281,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "su") (tramp-login-args (("-") ("%u"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) ;;;###tramp-autoload @@ -255,6 +292,7 @@ detected as prompt when being sent on echoing hosts, therefore.") ;; Local $SHELL could be a nasty one, like zsh or fish. Let's override it. (tramp-login-env (("SHELL") ("/bin/sh"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) ;;;###tramp-autoload @@ -263,6 +301,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "ksu") (tramp-login-args (("%u") ("-q"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-connection-timeout 10))) ;;;###tramp-autoload @@ -271,6 +310,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "krlogin") (tramp-login-args (("%h") ("-l" "%u") ("-x"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -285,6 +325,7 @@ detected as prompt when being sent on echoing hosts, therefore.") tramp-initial-end-of-output)) ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-default-port 22))) ;;;###tramp-autoload @@ -298,6 +339,7 @@ detected as prompt when being sent on echoing hosts, therefore.") tramp-initial-end-of-output)) ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -311,6 +353,7 @@ detected as prompt when being sent on echoing hosts, therefore.") tramp-initial-end-of-output)) ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-scp") ("-p" "%k") @@ -330,6 +373,7 @@ detected as prompt when being sent on echoing hosts, therefore.") tramp-initial-end-of-output)) ("/bin/sh") ("\""))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k") @@ -342,6 +386,7 @@ detected as prompt when being sent on echoing hosts, therefore.") (tramp-login-program "fsh") (tramp-login-args (("%h") ("-l" "%u") ("sh" "-i"))) (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-login ("-l")) (tramp-remote-shell-args ("-i") ("-c")) (tramp-copy-program "fcp") (tramp-copy-args (("-p" "%k"))) @@ -471,9 +516,8 @@ as given in your `~/.profile'." (defcustom tramp-remote-process-environment `("TMOUT=0" "LC_CTYPE=''" ,(format "TERM=%s" tramp-terminal-type) - "EMACS=t" ;; Deprecated. ,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version) - "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=\"\"" + "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat" "autocorrect=" "correct=") "List of environment variables to be set on the remote host. @@ -487,6 +531,7 @@ not be set here. Instead, it should be set via `tramp-remote-path'." :version "24.4" :type '(repeat string)) +;;;###tramp-autoload (defcustom tramp-sh-extra-args '(("/bash\\'" . "-norc -noprofile")) "Alist specifying extra arguments to pass to the remote shell. Entries are (REGEXP . ARGS) where REGEXP is a regular expression @@ -629,6 +674,7 @@ if (!@stat) { if (($stat[2] & 0170000) == 0120000) { $type = readlink($ARGV[0]); + $type =~ s/\"/\\\\\"/g; $type = \"\\\"$type\\\"\"; } elsif (($stat[2] & 0170000) == 040000) @@ -678,6 +724,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) @@ -690,6 +737,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, @@ -1146,15 +1194,19 @@ target of the symlink differ." (tramp-message vec 5 "file attributes with ls: %s" localname) (tramp-send-command vec - (format "(%s %s || %s -h %s) && %s %s %s" + (format "(%s %s || %s -h %s) && %s %s %s %s" (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) + ;; On systems which have no quoting style, file names + ;; with special characters could fail. + (if (tramp-get-ls-command-with-quoting-style vec) + "--quoting-style=c" "") (if (eq id-format 'integer) "-ildn" "-ild") (tramp-shell-quote-argument localname))) - ;; parse `ls -l' output ... + ;; Parse `ls -l' output ... (with-current-buffer (tramp-get-buffer vec) (when (> (buffer-size) 0) (goto-char (point-min)) @@ -1193,11 +1245,14 @@ target of the symlink differ." ;; From the file modes, figure out other stuff. (setq symlinkp (eq ?l (aref res-filemodes 0))) (setq dirp (eq ?d (aref res-filemodes 0))) - ;; if symlink, find out file name pointed to + ;; If symlink, find out file name pointed to. (when symlinkp (search-forward "-> ") - (setq res-symlink-target (buffer-substring (point) (point-at-eol)))) - ;; return data gathered + (setq res-symlink-target + (if (tramp-get-ls-command-with-quoting-style vec) + (read (current-buffer)) + (buffer-substring (point) (point-at-eol))))) + ;; Return data gathered. (list ;; 0. t for directory, string (name linked to) for symbolic ;; link, or nil. @@ -1220,9 +1275,9 @@ target of the symlink differ." ;; 8. File modes, as a string of ten letters or dashes as in ls -l. res-filemodes ;; 9. t if file's gid would change if file were deleted and - ;; recreated. Will be set in `tramp-convert-file-attributes' + ;; recreated. Will be set in `tramp-convert-file-attributes'. t - ;; 10. inode number. + ;; 10. Inode number. res-inode ;; 11. Device number. Will be replaced by a virtual device number. -1 @@ -1246,16 +1301,21 @@ target of the symlink differ." (tramp-send-command-and-read vec (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)" + (concat + ;; On Opsware, pdksh (which is the true name of ksh there) + ;; doesn't parse correctly the sequence "((". Therefore, we add + ;; a space. Apostrophes in the stat output are masked as "//", + ;; in order to make a proper shell escape of them in file names. + "( (%s %s || %s -h %s) && (%s -c " + "'((//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " + "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g') || echo nil)") (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) (tramp-shell-quote-argument localname) (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" "//%U//") + (if (eq id-format 'integer) "%ge0" "//%G//") (tramp-shell-quote-argument localname)))) (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) @@ -1347,6 +1407,7 @@ of." (defun tramp-sh-handle-set-file-modes (filename mode) "Like `set-file-modes' for Tramp files." (with-parsed-tramp-file-name filename nil + (tramp-flush-file-property v (file-name-directory localname)) (tramp-flush-file-property v localname) ;; FIXME: extract the proper text from chmod's stderr. (tramp-barf-unless-okay @@ -1361,6 +1422,7 @@ of." (if (tramp-tramp-file-p filename) (with-parsed-tramp-file-name filename nil (when (tramp-get-remote-touch v) + (tramp-flush-file-property v (file-name-directory localname)) (tramp-flush-file-property v localname) (let ((time (if (or (null time) (equal time '(0 0))) (current-time) @@ -1419,12 +1481,14 @@ be non-negative integers." (tramp-shell-quote-argument localname)))))) ;; We handle also the local part, because there doesn't exist - ;; `set-file-uid-gid'. On W32 "chown" might not work. - (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer))) - (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer)))) - (tramp-call-process - nil "chown" nil nil nil - (format "%d:%d" uid gid) (tramp-shell-quote-argument filename)))))) + ;; `set-file-uid-gid'. On W32 "chown" might not work. We add a + ;; timeout for this. + (with-timeout (5 nil) + (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer))) + (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer)))) + (tramp-call-process + nil "chown" nil nil nil + (format "%d:%d" uid gid) (tramp-shell-quote-argument filename))))))) (defun tramp-remote-selinux-p (vec) "Check, whether SELINUX is enabled on the remote host." @@ -1493,7 +1557,7 @@ be non-negative integers." (when (and (tramp-remote-acl-p v) (tramp-send-command-and-check v (format - "getfacl -ac %s 2>/dev/null" + "getfacl -ac %s" (tramp-shell-quote-argument localname)))) (with-current-buffer (tramp-get-connection-buffer v) (goto-char (point-max)) @@ -1518,7 +1582,7 @@ be non-negative integers." (progn (tramp-set-file-property v localname "file-acl" acl-string) t) - ;; In case of errors, we return `nil'. + ;; In case of errors, we return nil. (tramp-set-file-property v localname "file-acl-string" 'undef) nil))) @@ -1624,45 +1688,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) @@ -1689,17 +1752,22 @@ be non-negative integers." (concat ;; 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 | " + ;; but it does not work on all remote systems. Apostrophes in + ;; the stat output are masked as "//", 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 \")\"") + "'(//%%n// (//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " + "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g'); echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) + ;; On systems which have no quoting 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" "//%U//") + (if (eq id-format 'integer) "%ge0" "//%G//")))) ;; This function should return "foo/" for directories and "bar" for ;; files. @@ -1770,7 +1838,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 @@ -1794,7 +1862,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)))) @@ -1911,7 +1979,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'" (t2 (tramp-tramp-file-p newname))) (with-parsed-tramp-file-name (if t1 dirname newname) nil (if (and (not copy-contents) - (tramp-get-method-parameter method 'tramp-copy-recursive) + (tramp-get-method-parameter v 'tramp-copy-recursive) ;; When DIRNAME and NEWNAME are remote, they must have ;; the same method. (or (null t1) (null t2) @@ -2076,23 +2144,22 @@ 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. `epa-file-handler' shall not + ;; be called either. 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-operation 'write-region) + (inhibit-file-name-handlers + (cons 'epa-file-handler + (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. @@ -2334,7 +2401,7 @@ The method used must be an out-of-band method." (tramp-get-connection-property v "login-as" nil))) ;; Check for listener port. - (when (tramp-get-method-parameter method 'tramp-remote-copy-args) + (when (tramp-get-method-parameter v 'tramp-remote-copy-args) (setq listener (number-to-string (+ 50000 (random 10000)))) (while (zerop (tramp-call-process v "nc" nil nil nil "-z" host listener)) @@ -2347,17 +2414,13 @@ The method used must be an out-of-band method." spec (format-spec-make ?t (tramp-get-connection-property (tramp-get-connection-process v) "temp-file" "")) - options (format-spec - (if tramp-use-ssh-controlmaster-options - tramp-ssh-controlmaster-options "") - spec) + options (format-spec (tramp-ssh-controlmaster-options v) spec) spec (format-spec-make ?h host ?u user ?p port ?r listener ?c options ?k (if keep-date " " "")) - copy-program (tramp-get-method-parameter - method 'tramp-copy-program) + copy-program (tramp-get-method-parameter v 'tramp-copy-program) copy-keep-date (tramp-get-method-parameter - method 'tramp-copy-keep-date) + v 'tramp-copy-keep-date) copy-args (delete @@ -2366,9 +2429,7 @@ The method used must be an out-of-band method." ;; for the whole keep-date sublist. " " (dolist - (x - (tramp-get-method-parameter method 'tramp-copy-args) - copy-args) + (x (tramp-get-method-parameter v 'tramp-copy-args) copy-args) (setq copy-args (append copy-args @@ -2382,16 +2443,12 @@ The method used must be an out-of-band method." (lambda (x) (setq x (mapcar (lambda (y) (format-spec y spec)) x)) (unless (member "" x) (mapconcat 'identity x " "))) - (tramp-get-method-parameter method 'tramp-copy-env))) + (tramp-get-method-parameter v 'tramp-copy-env))) remote-copy-program - (tramp-get-method-parameter method 'tramp-remote-copy-program)) + (tramp-get-method-parameter v 'tramp-remote-copy-program)) - (dolist - (x - (or - (tramp-get-connection-property v "remote-copy-args" nil) - (tramp-get-method-parameter method 'tramp-remote-copy-args))) + (dolist (x (tramp-get-method-parameter v 'tramp-remote-copy-args)) (setq remote-copy-args (append remote-copy-args @@ -2422,10 +2479,10 @@ The method used must be an out-of-band method." " ")) (tramp-send-command v remote-copy-program) (with-timeout - (1 (tramp-error - v 'file-error - "Listener process not running on remote host: `%s'" - remote-copy-program)) + (60 (tramp-error + v 'file-error + "Listener process not running on remote host: `%s'" + remote-copy-program)) (tramp-send-command v (format "netstat -l | grep -q :%s" listener)) (while (not (tramp-send-command-and-check v nil)) (tramp-send-command @@ -2539,7 +2596,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))) @@ -2797,7 +2854,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))))) @@ -2856,10 +2913,15 @@ the result will be a local, non-Tramp, file name." (setq i (+ i 250)))) (cdr args))) ;; Use a human-friendly prompt, for example for `shell'. - (prompt (format "PS1=%s" - (format "%s %s" - (file-remote-p default-directory) - tramp-initial-end-of-output))) + ;; We discard hops, if existing, that's why we cannot use + ;; `file-remote-p'. + (prompt (format "PS1=%s %s" + (tramp-make-tramp-file-name + (tramp-file-name-method v) + (tramp-file-name-user v) + (tramp-file-name-host v) + (tramp-file-name-localname v)) + tramp-initial-end-of-output)) ;; We use as environment the difference to toplevel ;; `process-environment'. env @@ -3035,7 +3097,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) @@ -3065,9 +3127,9 @@ the result will be a local, non-Tramp, file name." (when tmpinput (delete-file tmpinput)) ;; `process-file-side-effects' has been introduced with GNU - ;; Emacs 23.2. If set to `nil', no remote file will be changed + ;; Emacs 23.2. If set to nil, no remote file will be changed ;; by `program'. If it doesn't exist, we assume its default - ;; value `t'. + ;; value t. (unless (and (boundp 'process-file-side-effects) (not (symbol-value 'process-file-side-effects))) (tramp-flush-directory-property v "")) @@ -3114,17 +3176,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. @@ -3170,7 +3229,8 @@ the result will be a local, non-Tramp, file name." (if (fboundp 'find-buffer-file-type) (symbol-function 'find-buffer-file-type) nil)) - (inhibit-file-name-handlers '(jka-compr-handler image-file-handler)) + (inhibit-file-name-handlers + '(epa-file-handler image-file-handler jka-compr-handler)) (inhibit-file-name-operation 'insert-file-contents)) (unwind-protect (progn @@ -3293,8 +3353,7 @@ the result will be a local, non-Tramp, file name." (if (and (not (stringp start)) (= (or end (point-max)) (point-max)) (= (or start (point-min)) (point-min)) - (tramp-get-method-parameter - method 'tramp-copy-keep-tmpfile)) + (tramp-get-method-parameter v 'tramp-copy-keep-tmpfile)) (progn (setq tramp-temp-buffer-file-name tmpfile) (condition-case err @@ -3700,29 +3759,22 @@ Only send the definition if it has not already been done." (tramp-get-connection-process vec) "scripts" nil))) (unless (member name scripts) (with-tramp-progress-reporter vec 5 (format "Sending script `%s'" name) + ;; In bash, leading TABs like in `tramp-vc-registered-read-file-names' + ;; could result in unwanted command expansion. Avoid this. + (setq script (tramp-compat-replace-regexp-in-string + (make-string 1 ?\t) (make-string 8 ? ) script)) ;; The script could contain a call of Perl. This is masked with `%s'. (when (and (string-match "%s" script) (not (tramp-get-remote-perl vec))) (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)))))) -(defun tramp-set-auto-save () - (when (and ;; ange-ftp has its own auto-save mechanism - (eq (tramp-find-foreign-file-name-handler (buffer-file-name)) - 'tramp-sh-file-name-handler) - auto-save-default) - (auto-save-mode 1))) -(add-hook 'find-file-hooks 'tramp-set-auto-save t) -(add-hook 'tramp-unload-hook - (lambda () - (remove-hook 'find-file-hooks 'tramp-set-auto-save))) - (defun tramp-run-test (switch filename) "Run `test' on the remote system, given a SWITCH and a FILENAME. Returns the exit code of the `test' program." @@ -3794,7 +3846,7 @@ This function expects to be in the right *tramp* buffer." (tramp-send-command vec (format (concat "while read d; " - "do if test -x $d/%s -a -f $d/%s; " + "do if test -x $d/%s && test -f $d/%s; " "then echo tramp_executable $d/%s; " "break; fi; done <<'%s'\n" "%s\n%s") @@ -3900,12 +3952,16 @@ file exists and nonzero exit status otherwise." ;; when called as sh) on startup; this way, we avoid the startup ;; file clobbering $PS1. $PROMPT_COMMAND is another way to set ;; the prompt in /bin/bash, it must be discarded as well. + ;; $HISTFILE is set according to `tramp-histfile-override'. (tramp-send-command vec (format - "exec env ENV=''%s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s" - (if tramp-histfile-override - (concat " HISTFILE=" tramp-histfile-override) - "") + "exec env ENV='' %s PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s" + (if (stringp tramp-histfile-override) + (format "HISTFILE=%s" + (tramp-shell-quote-argument tramp-histfile-override)) + (if tramp-histfile-override + "HISTFILE='' HISTFILESIZE=0 HISTSIZE=0" + "")) (tramp-shell-quote-argument tramp-end-of-output) shell (or extra-args "")) t)) @@ -3915,12 +3971,7 @@ file exists and nonzero exit status otherwise." (defun tramp-find-shell (vec) "Opens a shell on the remote host which groks tilde expansion." (with-current-buffer (tramp-get-buffer vec) - (let ((default-shell - (or - (tramp-get-connection-property - (tramp-get-connection-process vec) "remote-shell" nil) - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-remote-shell))) + (let ((default-shell (tramp-get-method-parameter vec 'tramp-remote-shell)) shell) (setq shell (with-tramp-connection-property vec "remote-shell" @@ -3979,15 +4030,11 @@ seconds. If not, it produces an error message with the given ERROR-ARGS." Mainly sets the prompt and the echo correctly. PROC is the shell process to set up. VEC specifies the connection." (let ((tramp-end-of-output tramp-initial-end-of-output)) - (tramp-open-shell - vec - (or (tramp-get-connection-property vec "remote-shell" nil) - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-remote-shell))) + (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell)) - ;; Disable echo. + ;; Disable tab and echo expansion. (tramp-message vec 5 "Setting up remote shell environment") - (tramp-send-command vec "stty -inlcr -echo kill '^U' erase '^H'" t) + (tramp-send-command vec "stty tab0 -inlcr -echo kill '^U' erase '^H'" t) ;; Check whether the echo has really been disabled. Some ;; implementations, like busybox of embedded GNU/Linux, don't ;; support disabling. @@ -4520,15 +4567,9 @@ Gateway hops are already opened." ;; Foreign and out-of-band methods are not supported for multi-hops. (when (cdr target-alist) (setq choices target-alist) - (while choices - (setq item (pop choices)) - (when - (or - (not - (tramp-get-method-parameter - (tramp-file-name-method item) 'tramp-login-program)) - (tramp-get-method-parameter - (tramp-file-name-method item) 'tramp-copy-program)) + (while (setq item (pop choices)) + (when (or (not (tramp-get-method-parameter item 'tramp-login-program)) + (tramp-get-method-parameter item 'tramp-copy-program)) (tramp-error vec 'file-error "Method `%s' is not supported for multi-hops." @@ -4536,7 +4577,7 @@ Gateway hops are already opened." ;; In case the host name is not used for the remote shell ;; command, the user could be misguided by applying a random - ;; hostname. + ;; host name. (let* ((v (car target-alist)) (method (tramp-file-name-method v)) (host (tramp-file-name-host v))) @@ -4545,8 +4586,7 @@ Gateway hops are already opened." ;; There are multi-hops. (cdr target-alist) ;; The host name is used for the remote shell command. - (member - '("%h") (tramp-get-method-parameter method 'tramp-login-args)) + (member '("%h") (tramp-get-method-parameter v 'tramp-login-args)) ;; The host is local. We cannot use `tramp-local-host-p' ;; here, because it opens a connection as well. (string-match tramp-local-host-regexp host)) @@ -4558,6 +4598,48 @@ Gateway hops are already opened." ;; Result. target-alist)) +(defun tramp-ssh-controlmaster-options (vec) + "Return the Control* arguments of the local ssh." + (cond + ;; No options to be computed. + ((or (null tramp-use-ssh-controlmaster-options) + (null (assoc "%c" (tramp-get-method-parameter vec 'tramp-login-args)))) + "") + + ;; There is already a value to be used. + ((stringp tramp-ssh-controlmaster-options) tramp-ssh-controlmaster-options) + + ;; Determine the options. + (t (setq tramp-ssh-controlmaster-options "") + (let ((case-fold-search t)) + (ignore-errors + (when (executable-find "ssh") + (with-temp-buffer + (tramp-call-process vec "ssh" nil t nil "-o" "ControlMaster") + (goto-char (point-min)) + (when (search-forward-regexp "missing.+argument" nil t) + (setq tramp-ssh-controlmaster-options "-o ControlMaster=auto"))) + (unless (zerop (length tramp-ssh-controlmaster-options)) + (with-temp-buffer + ;; We use a non-existing IP address, in order to avoid + ;; useless connections, and DNS timeouts. + (tramp-call-process + vec "ssh" nil t nil "-o" "ControlPath=%C" "0.0.0.1") + (goto-char (point-min)) + (setq tramp-ssh-controlmaster-options + (concat tramp-ssh-controlmaster-options + (if (search-forward-regexp "unknown.+key" nil t) + " -o ControlPath='tramp.%%r@%%h:%%p'" + " -o ControlPath='tramp.%%C'")))) + (with-temp-buffer + (tramp-call-process vec "ssh" nil t nil "-o" "ControlPersist") + (goto-char (point-min)) + (when (search-forward-regexp "missing.+argument" nil t) + (setq tramp-ssh-controlmaster-options + (concat tramp-ssh-controlmaster-options + " -o ControlPersist=no")))))))) + tramp-ssh-controlmaster-options))) + (defun tramp-maybe-open-connection (vec) "Maybe open a connection VEC. Does not do anything if a connection is already open, but re-opens the @@ -4627,15 +4709,19 @@ connection if a previous connection has died for some reason." (delete-process p)) (setenv "TERM" tramp-terminal-type) (setenv "LC_ALL" "en_US.utf8") - (when tramp-histfile-override - (setenv "HISTFILE" tramp-histfile-override)) + (if (stringp tramp-histfile-override) + (setenv "HISTFILE" tramp-histfile-override) + (if tramp-histfile-override + (progn + (setenv "HISTFILE") + (setenv "HISTFILESIZE" "0") + (setenv "HISTSIZE" "0")))) (setenv "PROMPT_COMMAND") (setenv "PS1" tramp-initial-end-of-output) (let* ((target-alist (tramp-compute-multi-hops vec)) ;; We will apply `tramp-ssh-controlmaster-options' ;; only for the first hop. - (options (if tramp-use-ssh-controlmaster-options - tramp-ssh-controlmaster-options "")) + (options (tramp-ssh-controlmaster-options vec)) (process-connection-type tramp-process-connection-type) (process-adaptive-read-buffering nil) (coding-system-for-read nil) @@ -4676,22 +4762,18 @@ connection if a previous connection has died for some reason." (l-host (tramp-file-name-host hop)) (l-port nil) (login-program - (tramp-get-method-parameter - l-method 'tramp-login-program)) + (tramp-get-method-parameter hop 'tramp-login-program)) (login-args - (tramp-get-method-parameter - l-method 'tramp-login-args)) + (tramp-get-method-parameter hop 'tramp-login-args)) (login-env - (tramp-get-method-parameter - l-method 'tramp-login-env)) + (tramp-get-method-parameter hop 'tramp-login-env)) (async-args - (tramp-get-method-parameter - l-method 'tramp-async-args)) + (tramp-get-method-parameter hop 'tramp-async-args)) (connection-timeout (tramp-get-method-parameter - l-method 'tramp-connection-timeout)) + hop 'tramp-connection-timeout)) (gw-args - (tramp-get-method-parameter l-method 'tramp-gw-args)) + (tramp-get-method-parameter hop 'tramp-gw-args)) (gw (let ((tramp-verbose 0)) (tramp-get-file-property hop "" "gateway" nil))) (g-method (and gw (tramp-file-name-method gw))) @@ -4879,8 +4961,8 @@ function waits for output unless NOOUTPUT is set." (vec command &optional subshell dont-suppress-err) "Run COMMAND and check its exit status. Sends `echo $?' along with the COMMAND for checking the exit status. -If COMMAND is nil, just sends `echo $?'. Returns `t' if the exit -status is 0, and `nil' otherwise. +If COMMAND is nil, just sends `echo $?'. Returns t if the exit +status is 0, and nil otherwise. If the optional argument SUBSHELL is non-nil, the command is executed in a subshell, ie surrounded by parentheses. If @@ -5029,14 +5111,17 @@ Return ATTR." "")) (defun tramp-make-copy-program-file-name (vec) - "Create a file name suitable to be passed to `scp' or `nc' and workalikes." + "Create a file name suitable for `scp', `pscp', or `nc' and workalikes." (let ((method (tramp-file-name-method vec)) (user (tramp-file-name-user vec)) (host (tramp-file-name-real-host vec)) - (localname (tramp-shell-quote-argument - (tramp-file-name-localname vec)))) + (localname (tramp-file-name-localname vec))) + (when (string-match tramp-ipv6-regexp host) + (setq host (format "[%s]" host))) + (unless (string-match "ftp$" method) + (setq localname (tramp-shell-quote-argument localname))) (cond - ((tramp-get-method-parameter method 'tramp-remote-copy-program) + ((tramp-get-method-parameter vec 'tramp-remote-copy-program) localname) ((not (zerop (length user))) (shell-quote-argument (format "%s@%s:%s" user host localname))) @@ -5046,7 +5131,7 @@ Return ATTR." "Return t if this is an out-of-band method, nil otherwise." (and ;; It shall be an out-of-band method. - (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program) + (tramp-get-method-parameter vec 'tramp-copy-program) ;; There must be a size, otherwise the file doesn't exist. (numberp size) ;; Either the file size is large enough, or (in rare cases) there @@ -5088,13 +5173,15 @@ Return ATTR." (tramp-send-command-and-read vec (format - "%s -l %s 'echo %s \\\"$PATH\\\"'" - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-remote-shell) + "%s %s %s 'echo %s \\\"$PATH\\\"'" + (tramp-get-method-parameter vec 'tramp-remote-shell) (mapconcat 'identity - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-remote-shell-args) + (tramp-get-method-parameter vec 'tramp-remote-shell-login) + " ") + (mapconcat + 'identity + (tramp-get-method-parameter vec 'tramp-remote-shell-args) " ") (tramp-shell-quote-argument tramp-end-of-heredoc)) nil (regexp-quote tramp-end-of-heredoc))))) @@ -5146,7 +5233,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))))) @@ -5188,6 +5276,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") @@ -5445,7 +5544,7 @@ If no corresponding command is found, nil is returned. Otherwise, either a string is returned which contains a `%s' mark to be used for the respective input or output file; or a Lisp function cell is returned to be applied on a buffer." - ;; We must catch the errors, because we want to return `nil', when + ;; We must catch the errors, because we want to return nil, when ;; no inline coding is found. (ignore-errors (let ((coding @@ -5475,16 +5574,20 @@ 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) + 'tramp-call-process-region ,vec (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 + 'tramp-call-process-region ,vec beg end (car (split-string ,compress)) t t nil (cdr (split-string ,compress)))) (,coding (point-min) (point-max))))) @@ -5530,8 +5633,6 @@ function cell is returned to be applied on a buffer." ;; * Don't use globbing for directories with many files, as this is ;; likely to produce long command lines, and some shells choke on ;; long command lines. -;; * Make it work for different encodings, and for different file name -;; encodings, too. (Daniel Pittman) ;; * Don't search for perl5 and perl. Instead, only search for perl and ;; then look if it's the right version (with `perl -v'). ;; * When editing a remote CVS controlled file as a different user, VC