;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
-;; Copyright (C) 1998-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
;; (copyright statements below in code to be updated with the above notice)
(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
: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.
:group 'tramp
:type 'string)
+;;;###tramp-autoload
+(defcustom tramp-histfile-override t
+ "When invoking a shell, override the HISTFILE with this value.
+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 "Unset HISTFILE" t)
+ (string :tag "Redirect to a file")))
+
;;;###tramp-autoload
(defconst tramp-color-escape-sequence-regexp "\e[[;0-9]+m"
"Escape sequences produced by the \"ls\" command.")
(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
,(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.
: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
if (($stat[2] & 0170000) == 0120000)
{
$type = readlink($ARGV[0]);
+ $type =~ s/\"/\\\\\"/g;
$type = \"\\\"$type\\\"\";
}
elsif (($stat[2] & 0170000) == 040000)
if (($stat[2] & 0170000) == 0120000)
{
$type = readlink($filename);
+ $type =~ s/\"/\\\\\"/g;
$type = \"\\\"$type\\\"\";
}
elsif (($stat[2] & 0170000) == 040000)
};
$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,
(defconst tramp-perl-encode
"%s -e '
# This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015 Free Software Foundation, Inc.
use strict;
my %%trans = do {
(defconst tramp-perl-decode
"%s -e '
# This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2015 Free Software Foundation, Inc.
use strict;
my %%trans = do {
(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))
;; 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.
;; 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
(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)
(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)
(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.
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
;; 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))))
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.
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 " " ""))
(tramp-set-connection-property p "vector" orig-vec)
(tramp-compat-set-process-query-on-exit-flag p nil)
- ;; When `shell-file-name' is "cmdproxy", we must adapt
- ;; `tramp-local-end-of-line' for sending the password.
- (let ((tramp-local-end-of-line
- (if (string-match "cmdproxy" shell-file-name)
- "\n" tramp-local-end-of-line)))
+ ;; We must adapt `tramp-local-end-of-line' for
+ ;; sending the password.
+ (let ((tramp-local-end-of-line tramp-rsh-end-of-line))
(tramp-process-actions
p v nil tramp-actions-copy-out-of-band))
(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)))
(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)))))
(list (replace-match " \\\\\n" nil nil (cadr args))))
(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 use as environment the difference to toplevel
+ ;; `process-environment'.
+ env
+ (env
+ (dolist
+ (elt
+ (cons prompt (nreverse (copy-sequence process-environment)))
+ env)
+ (or (member elt (default-toplevel-value 'process-environment))
+ (setq env (cons elt env)))))
(command
(when (stringp program)
- (format "cd %s && exec %s env PS1=%s %s"
+ (format "cd %s && exec %s env %s %s"
(tramp-shell-quote-argument localname)
(if heredoc (format "<<'%s'" tramp-end-of-heredoc) "")
- ;; Use a human-friendly prompt, for example for `shell'.
- (tramp-shell-quote-argument
- (format "%s %s"
- (file-remote-p default-directory)
- tramp-initial-end-of-output))
+ (mapconcat 'tramp-shell-quote-argument env " ")
(if heredoc
(format "%s\n(\n%s\n) </dev/tty\n%s"
program (car args) tramp-end-of-heredoc)
(error "Implementation does not handle immediate return"))
(with-parsed-tramp-file-name default-directory nil
- (let (command input tmpinput stderr tmpstderr outbuf ret)
+ (let (command env input tmpinput stderr tmpstderr outbuf ret)
;; Compute command.
(setq command (mapconcat 'tramp-shell-quote-argument
(cons program args) " "))
+ ;; We use as environment the difference to toplevel `process-environment'.
+ (setq env
+ (dolist (elt (nreverse (copy-sequence process-environment)) env)
+ (or (member elt (default-toplevel-value 'process-environment))
+ (setq env (cons elt env)))))
+ (when env
+ (setq command
+ (format
+ "env %s %s"
+ (mapconcat 'tramp-shell-quote-argument env " ") command)))
;; Determine input.
(if (null infile)
(setq input "/dev/null")
(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)
;; 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.
(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))))))
(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")
;; 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='' HISTFILE=/dev/null PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s %s"
+ "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))
;; 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)))
;; 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
+ (tramp-file-name-method 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
+ ;; When we use a non-existing host name, we could run
+ ;; into DNS timeouts. So we use "localhost" with an
+ ;; improper port, expecting nobody runs sshd on the
+ ;; telnet port.
+ (tramp-call-process
+ vec "ssh" nil t nil
+ "-p" "23" "-o" "ControlPath=%C" "localhost")
+ (goto-char (point-min))
+ (setq tramp-ssh-controlmaster-options
+ (if (search-forward-regexp "unknown.+key" nil t)
+ (concat tramp-ssh-controlmaster-options
+ " -o ControlPath='tramp.%%r@%%h:%%p'")
+ (concat tramp-ssh-controlmaster-options
+ " -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
(delete-process p))
(setenv "TERM" tramp-terminal-type)
(setenv "LC_ALL" "en_US.utf8")
- (setenv "HISTFILE" "/dev/null")
+ (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)
(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)))))
(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")
`(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