;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
-;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2016 Free Software Foundation, Inc.
;; (copyright statements below in code to be updated with the above notice)
"///%s#$"
(md5 (concat (prin1-to-string process-environment) (current-time-string))))
"String used to recognize end of output.
-The ‘$’ character at the end is quoted; the string cannot be
+The `$' character at the end is quoted; the string cannot be
detected as prompt when being sent on echoing hosts, therefore.")
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("sudo"
(tramp-login-program "sudo")
- (tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
+ ;; The password template must be masked. Otherwise, it could be
+ ;; interpreted as password prompt if the remote host echoes the command.
+ (tramp-login-args (("-u" "%u") ("-s") ("-H")
+ ("-p" "P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":")))
;; 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")
;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
;; GNU/Linux (Debian, Suse): /bin:/usr/bin
;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
+;; Darwin: /usr/bin:/bin:/usr/sbin:/sbin
;; IRIX64: /usr/bin
;;;###tramp-autoload
(defcustom tramp-remote-path
use File::Spec;
use Cwd \"realpath\";
+sub myrealpath {
+ my ($file) = @_;
+ return realpath($file) if -e $file;
+}
+
sub recursive {
my ($volume, @dirs) = @_;
- my $real = realpath(File::Spec->catpath(
+ my $real = myrealpath(File::Spec->catpath(
$volume, File::Spec->catdir(@dirs), \"\"));
if ($real) {
my ($vol, $dir) = File::Spec->splitpath($real, 1);
}
}
-$result = realpath($ARGV[0]);
+$result = myrealpath($ARGV[0]);
if (!$result) {
my ($vol, $dir) = File::Spec->splitpath($ARGV[0], 1);
($vol, @dirs) = recursive($vol, File::Spec->splitdir($dir));
$result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\");
}
-if ($ARGV[0] =~ /\\/$/) {
- $result = $result . \"/\";
-}
-
+$result =~ s/\"/\\\\\"/g;
print \"\\\"$result\\\"\\n\";
' \"$1\" 2>/dev/null"
"Perl script to produce output suitable for use with `file-truename'
(file-acl . tramp-sh-handle-file-acl)
(file-attributes . tramp-sh-handle-file-attributes)
(file-directory-p . tramp-sh-handle-file-directory-p)
- ;; `file-equal-p' performed by default handler.
+ (file-equal-p . tramp-handle-file-equal-p)
(file-executable-p . tramp-sh-handle-file-executable-p)
(file-exists-p . tramp-sh-handle-file-exists-p)
- ;; `file-in-directory-p' performed by default handler.
+ (file-in-directory-p . tramp-handle-file-in-directory-p)
(file-local-copy . tramp-sh-handle-file-local-copy)
(file-modes . tramp-handle-file-modes)
(file-name-all-completions . tramp-sh-handle-file-name-all-completions)
(file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
(file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
(file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-notify-valid-p . tramp-handle-file-notify-valid-p)
(file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
(file-readable-p . tramp-sh-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
method user host
(with-tramp-file-property v localname "file-truename"
(let ((result nil)) ; result steps in reverse order
- (tramp-message v 4 "Finding true name for ‘%s’" filename)
+ (tramp-message v 4 "Finding true name for `%s'" filename)
(cond
;; Use GNU readlink --canonicalize-missing where available.
((tramp-get-remote-readlink v)
;; Do it yourself. We bind `directory-sep-char' here for
;; XEmacs on Windows, which would otherwise use backslash.
- (t (let* ((directory-sep-char ?/)
- (steps (tramp-compat-split-string localname "/"))
- (localnamedir (tramp-run-real-handler
- 'file-name-as-directory (list localname)))
- (is-dir (string= localname localnamedir))
- (thisstep nil)
- (numchase 0)
- ;; Don't make the following value larger than
- ;; necessary. People expect an error message in
- ;; a timely fashion when something is wrong;
- ;; otherwise they might think that Emacs is hung.
- ;; Of course, correctness has to come first.
- (numchase-limit 20)
- symlink-target)
+ (t (let ((directory-sep-char ?/)
+ (steps (tramp-compat-split-string localname "/"))
+ (thisstep nil)
+ (numchase 0)
+ ;; Don't make the following value larger than
+ ;; necessary. People expect an error message in a
+ ;; timely fashion when something is wrong;
+ ;; otherwise they might think that Emacs is hung.
+ ;; Of course, correctness has to come first.
+ (numchase-limit 20)
+ symlink-target)
(while (and steps (< numchase numchase-limit))
(setq thisstep (pop steps))
(tramp-message
(list thisstep))
"/")))))
(cond ((string= "." thisstep)
- (tramp-message v 5 "Ignoring step ‘.’"))
+ (tramp-message v 5 "Ignoring step `.'"))
((string= ".." thisstep)
- (tramp-message v 5 "Processing step ‘..’")
+ (tramp-message v 5 "Processing step `..'")
(pop result))
((stringp symlink-target)
;; It's a symlink, follow it.
(unless (tramp-equal-remote filename symlink-target)
(tramp-error
v 'file-error
- "Symlink target ‘%s’ on wrong host"
+ "Symlink target `%s' on wrong host"
symlink-target))
(setq symlink-target localname))
(setq steps
(if result
(mapconcat 'identity (cons "" result) "/")
"/"))
- (when (and is-dir
- (or (string= "" result)
- (not (string= (substring result -1) "/"))))
- (setq result (concat result "/"))))))
+ (when (string= "" result)
+ (setq result "/")))))
- (tramp-message v 4 "True name of ‘%s’ is ‘%s’" localname result)
+ (tramp-message v 4 "True name of `%s' is `%s'" localname result)
result))))
;; Preserve trailing "/".
(tramp-get-test-command vec)
(tramp-shell-quote-argument localname)
(tramp-get-ls-command vec)
+ (if (eq id-format 'integer) "-ildn" "-ild")
;; 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")
+ (cond
+ ((tramp-get-ls-command-with-quoting-style vec)
+ "--quoting-style=c")
+ ((tramp-get-ls-command-with-w-option vec)
+ "-w")
+ (t ""))
(tramp-shell-quote-argument localname)))
;; Parse `ls -l' output ...
(with-current-buffer (tramp-get-buffer vec)
(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
"Like `set-visited-file-modtime' for Tramp files."
(unless (buffer-file-name)
- (error "Can’t set-visited-file-modtime: buffer ‘%s’ not visiting a file"
+ (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
(buffer-name)))
(if time-list
(tramp-run-real-handler 'set-visited-file-modtime (list time-list))
(format "chmod %s %s"
(tramp-compat-decimal-to-octal mode)
(tramp-shell-quote-argument localname))
- "Error while changing file’s mode %s" filename)))
+ "Error while changing file's mode %s" filename)))
(defun tramp-sh-handle-set-file-times (filename &optional time)
"Like `set-file-times' for Tramp files."
"-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%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" "")
+ ;; On systems which have no quoting style, file names with special
+ ;; characters could fail.
+ (cond
+ ((tramp-get-ls-command-with-quoting-style vec)
+ "--quoting-style=shell")
+ ((tramp-get-ls-command-with-w-option vec)
+ "-w")
+ (t ""))
(tramp-get-remote-stat vec)
tramp-stat-marker tramp-stat-marker
tramp-stat-marker tramp-stat-marker
(tramp-error
v 'file-error
"\
-tramp-sh-handle-file-name-all-completions: internal error accessing ‘%s’: ‘%s’"
+tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
(tramp-shell-quote-argument localname) (buffer-string))))
(while (zerop (forward-line -1))
(format "%s %s %s" ln
(tramp-shell-quote-argument v1-localname)
(tramp-shell-quote-argument v2-localname))
- "error with add-name-to-file, see buffer ‘%s’ for details"
+ "error with add-name-to-file, see buffer `%s' for details"
(buffer-name))))))
(defun tramp-sh-handle-copy-file
of `copy' and `rename'. FILENAME and NEWNAME must be absolute
file names."
(unless (memq op '(copy rename))
- (error "Unknown operation ‘%s’, must be ‘copy’ or ‘rename’" op))
+ (error "Unknown operation `%s', must be `copy' or `rename'" op))
(let ((t1 (tramp-tramp-file-p filename))
(t2 (tramp-tramp-file-p newname))
(length (nth 7 (file-attributes (file-truename filename))))
((eq op 'rename) "mv -f")
(t (tramp-error
v 'file-error
- "Unknown operation ‘%s’, must be ‘copy’ or ‘rename’"
+ "Unknown operation `%s', must be `copy' or `rename'"
op))))
(localname1
(if t1
cmd-result)
(tramp-error-with-buffer
nil v 'file-error
- "Copying directly failed, see buffer ‘%s’ for details."
+ "Copying directly failed, see buffer `%s' for details."
(buffer-name)))))
;; We are on the local host.
"%s %s %s" cmd
(tramp-shell-quote-argument localname1)
(tramp-shell-quote-argument tmpfile))
- "Copying directly failed, see buffer ‘%s’ for details."
+ "Copying directly failed, see buffer `%s' for details."
(tramp-get-buffer v))
;; We must change the ownership as remote user.
;; Since this does not work reliable, we also
"cp -f -p %s %s"
(tramp-shell-quote-argument tmpfile)
(tramp-shell-quote-argument localname2))
- "Copying directly failed, see buffer ‘%s’ for details."
+ "Copying directly failed, see buffer `%s' for details."
(tramp-get-buffer v)))
(t1
(tramp-run-real-handler
(setq source (if t1
(tramp-make-copy-program-file-name v)
(shell-quote-argument filename))
- target (funcall
+ target (if t2
+ (tramp-make-copy-program-file-name v)
+ (shell-quote-argument
+ (funcall
(if (and (file-directory-p filename)
(string-equal
(file-name-nondirectory filename)
(file-name-nondirectory newname)))
'file-name-directory
'identity)
- (if t2
- (tramp-make-copy-program-file-name v)
- (shell-quote-argument newname))))
+ newname))))
;; Check for host and port number. We cannot use
;; `tramp-file-name-port', because this returns also
(with-timeout
(60 (tramp-error
v 'file-error
- "Listener process not running on remote host: ‘%s’"
+ "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))
(re-search-backward "tramp_exit_status [0-9]+" nil t)
(tramp-error
orig-vec 'file-error
- "Couldn’t find exit status of ‘%s’"
+ "Couldn't find exit status of `%s'"
(mapconcat 'identity (process-command p) " ")))
(skip-chars-forward "^ ")
(unless (zerop (read (current-buffer)))
(forward-line -1)
(tramp-error
orig-vec 'file-error
- "Error copying: ‘%s’"
+ "Error copying: `%s'"
(buffer-substring (point-min) (point-at-eol))))))
;; Reset the transfer process properties.
v (format "%s %s"
(if parents "mkdir -p" "mkdir")
(tramp-shell-quote-argument localname))
- "Couldn’t make directory %s" dir))))
+ "Couldn't make directory %s" dir))))
(defun tramp-sh-handle-delete-directory (directory &optional recursive)
"Like `delete-directory' for Tramp files."
v (format "cd / && %s %s"
(if recursive "rm -rf" "rmdir")
(tramp-shell-quote-argument localname))
- "Couldn’t delete %s" directory)))
+ "Couldn't delete %s" directory)))
(defun tramp-sh-handle-delete-file (filename &optional trash)
"Like `delete-file' for Tramp files."
v (format "%s %s"
(or (and trash (tramp-get-remote-trash v)) "rm -f")
(tramp-shell-quote-argument localname))
- "Couldn’t delete %s" filename)))
+ "Couldn't delete %s" filename)))
;; Dired.
(when wildcard
(setq switches (concat switches " " wildcard)))
(tramp-message
- v 4 "Inserting directory ‘ls %s %s’, wildcard %s, fulldir %s"
+ v 4 "Inserting directory `ls %s %s', wildcard %s, fulldir %s"
switches filename (if wildcard "yes" "no")
(if full-directory-p "yes" "no"))
;; If `full-directory-p', we just say `ls -l FILENAME'.
(format "cd %s" (tramp-shell-quote-argument
(tramp-run-real-handler
'file-name-directory (list localname))))
- "Couldn’t ‘cd %s’"
+ "Couldn't `cd %s'"
(tramp-shell-quote-argument
(tramp-run-real-handler 'file-name-directory (list localname))))
(tramp-send-command
(unless (memq (process-status proc) '(run open))
(let ((vec (tramp-get-connection-property proc "vector" nil)))
(when vec
- (tramp-message vec 5 "Sentinel called: ‘%S’ ‘%s’" proc event)
+ (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event)
(tramp-flush-connection-property proc)
(tramp-flush-directory-property vec "")))))
(tramp-get-connection-process v) 'remote-tty)
(tramp-error
v 'file-error
- "pty association is not supported for ‘%s’" name))))
+ "pty association is not supported for `%s'" name))))
(let ((p (tramp-get-connection-process v)))
;; Set query flag and process marker for this
;; process. We ignore errors, because the process
(unless (file-exists-p filename)
(tramp-error
v 'file-error
- "Cannot make local copy of non-existing file ‘%s’" filename))
+ "Cannot make local copy of non-existing file `%s'" filename))
(let* ((size (nth 7 (file-attributes (file-truename filename))))
(rem-enc (tramp-get-inline-coding v "remote-encoding" size))
(save-excursion
(with-tramp-progress-reporter
v 3
- (format-message "Encoding remote file ‘%s’ with ‘%s’"
+ (format-message "Encoding remote file `%s' with `%s'"
filename rem-enc)
(tramp-barf-unless-okay
v (format rem-enc (tramp-shell-quote-argument localname))
"Encoding remote file failed"))
(with-tramp-progress-reporter
- v 3 (format-message "Decoding local file ‘%s’ with ‘%s’"
+ v 3 (format-message "Decoding local file `%s' with `%s'"
tmpfile loc-dec)
(if (functionp loc-dec)
;; If local decoding is a function, we call it.
;; Oops, I don't know what to do.
(t (tramp-error
- v 'file-error "Wrong method specification for ‘%s’" method)))
+ v 'file-error "Wrong method specification for `%s'" method)))
;; Error handling.
((error quit)
;; Use encoding function or command.
(with-tramp-progress-reporter
v 3 (format-message
- "Encoding local file ‘%s’ using ‘%s’"
+ "Encoding local file `%s' using `%s'"
tmpfile loc-enc)
(if (functionp loc-enc)
;; The following `let' is a workaround for
loc-enc tmpfile t))
(tramp-error
v 'file-error
- (concat "Cannot write to ‘%s’, "
- "local encoding command ‘%s’ failed")
+ (concat "Cannot write to `%s', "
+ "local encoding command `%s' failed")
filename loc-enc))))
;; Send buffer into remote decoding command which
;; the remote host, we cannot use the function.
(with-tramp-progress-reporter
v 3 (format-message
- "Decoding remote file ‘%s’ using ‘%s’"
+ "Decoding remote file `%s' using `%s'"
filename rem-dec)
(goto-char (point-max))
(unless (bolp) (newline))
tramp-end-of-heredoc))
(tramp-barf-unless-okay
v nil
- "Couldn’t write region to ‘%s’, decode using ‘%s’ failed"
+ "Couldn't write region to `%s', decode using `%s' failed"
filename rem-dec)
;; When `file-precious-flag' is set, the region is
;; written to a temporary file. Check that the
(buffer-string))))
(tramp-error
v 'file-error
- (concat "Couldn’t write region to ‘%s’,"
- " decode using ‘%s’ failed")
+ (concat "Couldn't write region to `%s',"
+ " decode using `%s' failed")
filename rem-dec)))))
;; Save exit.
(t
(tramp-error
v 'file-error
- (concat "Method ‘%s’ should specify both encoding and "
+ (concat "Method `%s' should specify both encoding and "
"decoding command or an scp program")
method))))
(tramp-compat-with-temp-message ""
(with-parsed-tramp-file-name file nil
(with-tramp-progress-reporter
- v 3 (format-message "Checking ‘vc-registered’ for %s" file)
+ v 3 (format-message "Checking `vc-registered' for %s" file)
;; There could be new files, created by the vc backend. We
;; cannot reuse the old cache entries, therefore. In
"Like `file-notify-add-watch' for Tramp files."
(setq file-name (expand-file-name file-name))
(with-parsed-tramp-file-name file-name nil
- (let* ((default-directory (file-name-directory file-name))
- command events filter p sequence)
+ (let ((default-directory (file-name-directory file-name))
+ command events filter p sequence)
(cond
;; gvfs-monitor-dir.
((setq command (tramp-get-remote-gvfs-monitor-dir v))
- (setq filter 'tramp-sh-file-gvfs-monitor-dir-process-filter
+ (setq filter 'tramp-sh-gvfs-monitor-dir-process-filter
+ events
+ (cond
+ ((and (memq 'change flags) (memq 'attribute-change flags))
+ '(created changed changes-done-hint moved deleted
+ attribute-changed))
+ ((memq 'change flags)
+ '(created changed changes-done-hint moved deleted))
+ ((memq 'attribute-change flags) '(attribute-changed)))
sequence `(,command ,localname)))
;; inotifywait.
((setq command (tramp-get-remote-inotifywait v))
- (setq filter 'tramp-sh-file-inotifywait-process-filter
+ (setq filter 'tramp-sh-inotifywait-process-filter
events
(cond
((and (memq 'change flags) (memq 'attribute-change flags))
- "create,modify,move,delete,attrib")
- ((memq 'change flags) "create,modify,move,delete")
- ((memq 'attribute-change flags) "attrib"))
+ (concat "create,modify,move,moved_from,moved_to,move_self,"
+ "delete,delete_self,attrib,ignored"))
+ ((memq 'change flags)
+ (concat "create,modify,move,moved_from,moved_to,move_self,"
+ "delete,delete_self,ignored"))
+ ((memq 'attribute-change flags) "attrib,ignored"))
sequence `(,command "-mq" "-e" ,events ,localname)))
;; None.
(t (tramp-error
(if (not (processp p))
(tramp-error
v 'file-notify-error
- "‘%s’ failed to start on remote host"
+ "`%s' failed to start on remote host"
(mapconcat 'identity sequence " "))
- (tramp-message v 6 "Run ‘%s’, %S" (mapconcat 'identity sequence " ") p)
+ (tramp-message v 6 "Run `%s', %S" (mapconcat 'identity sequence " ") p)
(tramp-set-connection-property p "vector" v)
+ ;; Needed for `tramp-sh-gvfs-monitor-dir-process-filter'.
+ (tramp-compat-process-put p 'events events)
+ (tramp-compat-process-put p 'watch-name localname)
(tramp-compat-set-process-query-on-exit-flag p nil)
(set-process-filter p filter)
+ ;; There might be an error if the monitor is not supported.
+ ;; Give the filter a chance to read the output.
+ (tramp-accept-process-output p 1)
+ (unless (memq (process-status p) '(run open))
+ (tramp-error
+ v 'file-notify-error "Monitoring not supported for `%s'" file-name))
p))))
-(defun tramp-sh-file-gvfs-monitor-dir-process-filter (proc string)
- "Read output from \"gvfs-monitor-dir\" and add corresponding file-notify events."
+(defun tramp-sh-gvfs-monitor-dir-process-filter (proc string)
+ "Read output from \"gvfs-monitor-dir\" and add corresponding \
+file-notify events."
(let ((remote-prefix
(with-current-buffer (process-buffer proc)
(file-remote-p default-directory)))
;; Attribute change is returned in unused wording.
string (tramp-compat-replace-regexp-in-string
"ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
+ (when (string-match "Monitoring not supported" string)
+ (delete-process proc))
(while (string-match
(concat "^[\n\r]*"
"\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?"
"Event = \\([^[:blank:]]+\\)[\n\r]+")
string)
- (let ((object
- (list
- proc
- (intern-soft
- (tramp-compat-replace-regexp-in-string
- "_" "-" (downcase (match-string 4 string))))
- ;; File names are returned as absolute paths. We must
- ;; add the remote prefix.
- (concat remote-prefix (match-string 1 string))
- (when (match-string 3 string)
- (concat remote-prefix (match-string 3 string))))))
+ (let* ((file (match-string 1 string))
+ (file1 (match-string 3 string))
+ (object
+ (list
+ proc
+ (intern-soft
+ (tramp-compat-replace-regexp-in-string
+ "_" "-" (downcase (match-string 4 string))))
+ ;; File names are returned as absolute paths. We must
+ ;; add the remote prefix.
+ (concat remote-prefix file)
+ (when file1 (concat remote-prefix file1)))))
(setq string (replace-match "" nil nil string))
+ ;; Remove watch when file or directory to be watched is deleted.
+ (when (and (member (cadr object) '(moved deleted))
+ (string-equal
+ file (tramp-compat-process-get proc 'watch-name)))
+ (delete-process proc))
;; Usually, we would add an Emacs event now. Unfortunately,
;; `unread-command-events' does not accept several events at
;; once. Therefore, we apply the callback directly.
- (tramp-compat-funcall 'file-notify-callback object)))
+ (when (member (cadr object) (tramp-compat-process-get proc 'events))
+ (tramp-compat-funcall 'file-notify-callback object))))
;; Save rest of the string.
(when (zerop (length string)) (setq string nil))
(when string (tramp-message proc 10 "Rest string:\n%s" string))
(tramp-compat-process-put proc 'rest-string string)))
-(defun tramp-sh-file-inotifywait-process-filter (proc string)
+(defun tramp-sh-inotifywait-process-filter (proc string)
"Read output from \"inotifywait\" and add corresponding file-notify events."
(tramp-message proc 6 "%S\n%s" proc string)
(dolist (line (split-string string "[\n\r]+" 'omit-nulls))
(tramp-compat-replace-regexp-in-string "_" "-" (downcase x))))
(split-string (match-string 1 line) "," 'omit-nulls))
(match-string 3 line))))
+ ;; Remove watch when file or directory to be watched is deleted.
+ (when (equal (cadr object) 'ignored)
+ (delete-process proc))
;; Usually, we would add an Emacs event now. Unfortunately,
;; `unread-command-events' does not accept several events at
;; once. Therefore, we apply the callback directly.
(tramp-get-connection-process vec) "scripts" nil)))
(unless (member name scripts)
(with-tramp-progress-reporter
- vec 5 (format-message "Sending script ‘%s’" name)
+ vec 5 (format-message "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
(not (tramp-send-command-and-check
vec (format "%s %s" result nonexistent))))))
(tramp-error
- vec 'file-error "Couldn’t find command to check if file exists"))
+ vec 'file-error "Couldn't find command to check if file exists"))
result))
(defun tramp-open-shell (vec shell)
"Opens shell SHELL."
(with-tramp-progress-reporter
- vec 5 (format-message "Opening remote shell ‘%s’" shell)
+ vec 5 (format-message "Opening remote shell `%s'" shell)
;; Find arguments for this shell.
(let ((alist tramp-sh-extra-args)
item extra-args)
(tramp-message
vec 2
(concat
- "Couldn’t find a remote shell which groks tilde "
- "expansion, using ‘%s’")
+ "Couldn't find a remote shell which groks tilde "
+ "expansion, using `%s'")
default-shell)))
default-shell)))
;; Open a new shell if needed.
(unless (string-equal shell default-shell)
(tramp-message
- vec 5 "Starting remote shell ‘%s’ for tilde expansion" shell)
+ vec 5 "Starting remote shell `%s' for tilde expansion" shell)
(tramp-open-shell vec shell)))))
;; Utility functions.
"Set up an interactive shell.
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))
+ (let ((tramp-end-of-output tramp-initial-end-of-output)
+ (case-fold-search t))
(tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
;; Disable tab and echo expansion.
(tramp-message vec 5 "Setting up remote shell environment")
- (tramp-send-command vec "stty tab0 -inlcr -echo kill '^U' erase '^H'" t)
+ (tramp-send-command
+ vec "stty tab0 -inlcr -onlcr -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.
vec (format "PS1=%s PS2='' PS3='' PROMPT_COMMAND=''"
(tramp-shell-quote-argument tramp-end-of-output)) t)
+ ;; Check whether the output of "uname -sr" has been changed. If
+ ;; yes, this is a strong indication that we must expire all
+ ;; connection properties. We start again with
+ ;; `tramp-maybe-open-connection', it will be caught there.
+ (tramp-message vec 5 "Checking system information")
+ (let ((old-uname (tramp-get-connection-property vec "uname" nil))
+ (new-uname
+ (tramp-set-connection-property
+ vec "uname"
+ (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
+ (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
+ (tramp-message
+ vec 3
+ "Connection reset, because remote host changed from `%s' to `%s'"
+ old-uname new-uname)
+ ;; We want to keep the password.
+ (tramp-cleanup-connection vec t t)
+ (throw 'uname-changed (tramp-maybe-open-connection vec))))
+
;; Try to set up the coding system correctly.
;; CCC this can't be the right way to do it. Hm.
(tramp-message vec 5 "Determining coding system")
;; Use MULE to select the right EOL convention for communicating
;; with the process.
(let ((cs (or (and (memq 'utf-8 (coding-system-list))
- (string-match "utf8" (tramp-get-remote-locale vec))
+ (string-match "utf-?8" (tramp-get-remote-locale vec))
(cons 'utf-8 'utf-8))
(tramp-compat-funcall 'process-coding-system proc)
(cons 'undecided 'undecided)))
(setq cs-encode (cdr cs))
(unless cs-decode (setq cs-decode 'undecided))
(unless cs-encode (setq cs-encode 'undecided))
- (setq cs-encode (tramp-compat-coding-system-change-eol-conversion
- cs-encode 'unix))
+ (setq cs-encode
+ (tramp-compat-coding-system-change-eol-conversion
+ cs-encode
+ (if (string-match
+ "^Darwin" (tramp-get-connection-property vec "uname" ""))
+ 'mac 'unix)))
(tramp-send-command vec "echo foo ; echo bar" t)
(goto-char (point-min))
(when (search-forward "\r" nil t)
(tramp-compat-funcall
'set-buffer-process-coding-system cs-decode cs-encode)
(tramp-message
- vec 5 "Setting coding system to ‘%s’ and ‘%s’" cs-decode cs-encode))
+ vec 5 "Setting coding system to `%s' and `%s'" cs-decode cs-encode))
;; Look for ^M and do something useful if found.
(when (search-forward "\r" nil t)
;; We have found a ^M but cannot frob the process coding system
(tramp-send-command vec "set +o vi +o emacs" t)
- ;; Check whether the output of "uname -sr" has been changed. If
- ;; yes, this is a strong indication that we must expire all
- ;; connection properties. We start again with
- ;; `tramp-maybe-open-connection', it will be caught there.
- (tramp-message vec 5 "Checking system information")
- (let ((old-uname (tramp-get-connection-property vec "uname" nil))
- (new-uname
- (tramp-set-connection-property
- vec "uname"
- (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
- (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
- (tramp-message
- vec 3
- "Connection reset, because remote host changed from ‘%s’ to ‘%s’"
- old-uname new-uname)
- ;; We want to keep the password.
- (tramp-cleanup-connection vec t t)
- (throw 'uname-changed (tramp-maybe-open-connection vec))))
-
;; Check whether the remote host suffers from buggy
;; `send-process-string'. This is known for FreeBSD (see comment in
;; `send_process', file process.c). I've tested sending 624 bytes
tramp-chunksize)
(t
(tramp-message
- vec 5 "Checking remote host type for ‘send-process-string’ bug")
+ vec 5 "Checking remote host type for `send-process-string' bug")
(if (string-match
"^FreeBSD" (tramp-get-connection-property vec "uname" ""))
500 0))))
(tramp-find-shell vec)
;; Disable unexpected output.
- (tramp-send-command vec "mesg n; biff n" t)
+ (tramp-send-command vec "mesg n 2>/dev/null; biff n 2>/dev/null" t)
;; IRIX64 bash expands "!" even when in single quotes. This
;; destroys our shell functions, we must disable it. See
(tramp-get-connection-property vec "uname" ""))
(tramp-send-command vec "stty -oxtabs" t))
+ ;; Set utf8 encoding. Needed for Mac OS X, for example. This is
+ ;; non-POSIX, so we must expect errors on some systems.
+ (tramp-send-command vec "stty iutf8 2>/dev/null" t)
+
;; Set `remote-tty' process property.
(let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
(unless (zerop (length tty))
"List of local coding commands for inline transfer.
Each item is a list that looks like this:
-\(FORMAT ENCODING DECODING\)
+\(FORMAT ENCODING DECODING)
FORMAT is symbol describing the encoding/decoding format. It can be
`b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
;; However, I don't know whether all base64 versions do supports
;; this option.
(b64 "base64" "base64 -d")
+ (b64 "openssl enc -base64" "openssl enc -d -base64")
(b64 "mimencode -b" "mimencode -u -b")
(b64 "mmencode -b" "mmencode -u -b")
(b64 "recode data..base64" "recode base64..data")
"List of remote coding commands for inline transfer.
Each item is a list that looks like this:
-\(FORMAT ENCODING DECODING [TEST]\)
+\(FORMAT ENCODING DECODING [TEST])
FORMAT is a symbol describing the encoding/decoding format. It can be
`b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
;; corresponding command has to work locally.
(if (not (stringp loc-enc))
(tramp-message
- vec 5 "Checking local encoding function ‘%s’" loc-enc)
+ vec 5 "Checking local encoding function `%s'" loc-enc)
(tramp-message
- vec 5 "Checking local encoding command ‘%s’ for sanity" loc-enc)
+ vec 5 "Checking local encoding command `%s' for sanity" loc-enc)
(unless (zerop (tramp-call-local-coding-command
loc-enc nil nil))
(throw 'wont-work-local nil)))
(if (not (stringp loc-dec))
(tramp-message
- vec 5 "Checking local decoding function ‘%s’" loc-dec)
+ vec 5 "Checking local decoding function `%s'" loc-dec)
(tramp-message
- vec 5 "Checking local decoding command ‘%s’ for sanity" loc-dec)
+ vec 5 "Checking local decoding command `%s' for sanity" loc-dec)
(unless (zerop (tramp-call-local-coding-command
loc-dec nil nil))
(throw 'wont-work-local nil)))
;; Check the remote test command if exists.
(when (stringp rem-test)
(tramp-message
- vec 5 "Checking remote test command ‘%s’" rem-test)
+ vec 5 "Checking remote test command `%s'" rem-test)
(unless (tramp-send-command-and-check vec rem-test t)
(throw 'wont-work-remote nil)))
;; Check if remote perl exists when necessary.
(setq rem-enc name)))
(tramp-message
vec 5
- "Checking remote encoding command ‘%s’ for sanity" rem-enc)
+ "Checking remote encoding command `%s' for sanity" rem-enc)
(unless (tramp-send-command-and-check
vec (format "%s </dev/null" rem-enc) t)
(throw 'wont-work-remote nil))
(setq rem-dec name)))
(tramp-message
vec 5
- "Checking remote decoding command ‘%s’ for sanity" rem-dec)
+ "Checking remote decoding command `%s' for sanity" rem-dec)
(unless (tramp-send-command-and-check
vec
(format "echo %s | %s | %s" magic rem-enc rem-dec)
(when found
;; Set connection properties. Since the commands are risky
;; (due to output direction), we cache them in the process cache.
- (tramp-message vec 5 "Using local encoding ‘%s’" loc-enc)
+ (tramp-message vec 5 "Using local encoding `%s'" loc-enc)
(tramp-set-connection-property p "local-encoding" loc-enc)
- (tramp-message vec 5 "Using local decoding ‘%s’" loc-dec)
+ (tramp-message vec 5 "Using local decoding `%s'" loc-dec)
(tramp-set-connection-property p "local-decoding" loc-dec)
- (tramp-message vec 5 "Using remote encoding ‘%s’" rem-enc)
+ (tramp-message vec 5 "Using remote encoding `%s'" rem-enc)
(tramp-set-connection-property p "remote-encoding" rem-enc)
- (tramp-message vec 5 "Using remote decoding ‘%s’" rem-dec)
+ (tramp-message vec 5 "Using remote decoding `%s'" rem-dec)
(tramp-set-connection-property p "remote-decoding" rem-dec)))))
(defun tramp-call-local-coding-command (cmd input output)
"List of compress and decompress commands for inline transfer.
Each item is a list that looks like this:
-\(COMPRESS DECOMPRESS\)
+\(COMPRESS DECOMPRESS)
COMPRESS or DECOMPRESS are strings with the respective commands.")
decompress (nth 1 item))
(tramp-message
vec 5
- "Checking local compress commands ‘%s’, ‘%s’ for sanity"
+ "Checking local compress commands `%s', `%s' for sanity"
compress decompress)
(unless
(zerop
(throw 'next nil))
(tramp-message
vec 5
- "Checking remote compress commands ‘%s’, ‘%s’ for sanity"
+ "Checking remote compress commands `%s', `%s' for sanity"
compress decompress)
(unless (tramp-send-command-and-check
vec (format "echo %s | %s | %s" magic compress decompress) t)
;; risky (due to output direction), we cache them in the
;; process cache.
(tramp-message
- vec 5 "Using inline transfer compress command ‘%s’" compress)
+ vec 5 "Using inline transfer compress command `%s'" compress)
(tramp-set-connection-property p "inline-compress" compress)
(tramp-message
- vec 5 "Using inline transfer decompress command ‘%s’" decompress)
+ vec 5 "Using inline transfer decompress command `%s'" decompress)
(tramp-set-connection-property p "inline-decompress" decompress))
(tramp-set-connection-property p "inline-compress" nil)
(tramp-set-connection-property p "inline-decompress" nil)
(tramp-message
- vec 2 "Couldn’t find an inline transfer compress command")))))
+ vec 2 "Couldn't find an inline transfer compress command")))))
(defun tramp-compute-multi-hops (vec)
"Expands VEC according to `tramp-default-proxies-alist'.
(unless (tramp-file-name-port hop)
(tramp-error
vec 'file-error
- "Connection ‘%s’ is not supported for gateway access." hop))
+ "Connection `%s' is not supported for gateway access." hop))
;; Open the gateway connection.
(push
(vector
(tramp-get-method-parameter item 'tramp-copy-program))
(tramp-error
vec 'file-error
- "Method ‘%s’ is not supported for multi-hops."
+ "Method `%s' is not supported for multi-hops."
(tramp-file-name-method item)))))
;; In case the host name is not used for the remote shell
(string-match tramp-local-host-regexp host))
(tramp-error
v 'file-error
- "Host ‘%s’ looks like a remote host, ‘%s’ can only use the local host"
+ "Host `%s' looks like a remote host, `%s' can only use the local host"
host method)))
;; Result.
;; Check whether process is alive.
(tramp-barf-if-no-shell-prompt
p 10
- "Couldn’t find local shell prompt for %s" tramp-encoding-shell)
+ "Couldn't find local shell prompt for %s" tramp-encoding-shell)
;; Now do all the connections as specified.
(while target-alist
(when r-shell " && exit || exit")))
;; Send the command.
- (tramp-message vec 3 "Sending command ‘%s’" command)
+ (tramp-message vec 3 "Sending command `%s'" command)
(tramp-send-command vec command t t)
(tramp-process-actions
p vec pos tramp-actions-before-shell
(or connection-timeout tramp-connection-timeout))
(tramp-message
- vec 3 "Found remote shell prompt on ‘%s’" l-host))
+ vec 3 "Found remote shell prompt on `%s'" l-host))
;; Next hop.
(setq options ""
target-alist (cdr target-alist)))
"Wait for output from remote command."
(unless (buffer-live-p (process-buffer proc))
(delete-process proc)
- (tramp-error proc 'file-error "Process ‘%s’ not available, try again" proc))
+ (tramp-error proc 'file-error "Process `%s' not available, try again" proc))
(with-current-buffer (process-buffer proc)
(let* (;; Initially, `tramp-end-of-output' is "#$ ". There might
;; be leading escape sequences, which must be ignored.
(if timeout
(tramp-error
proc 'file-error
- "[[Remote prompt ‘%s’ not found in %d secs]]"
+ "[[Remote prompt `%s' not found in %d secs]]"
tramp-end-of-output timeout)
(tramp-error
proc 'file-error
- "[[Remote prompt ‘%s’ not found]]" tramp-end-of-output)))
+ "[[Remote prompt `%s' not found]]" tramp-end-of-output)))
;; Return value is whether end-of-output sentinel was found.
found)))
(goto-char (point-max))
(unless (re-search-backward "tramp_exit_status [0-9]+" nil t)
(tramp-error
- vec 'file-error "Couldn’t find exit status of ‘%s’" command))
+ vec 'file-error "Couldn't find exit status of `%s'" command))
(skip-chars-forward "^ ")
(prog1
(zerop (read (current-buffer)))
(when (if noerror
(tramp-send-command-and-check vec command)
(tramp-barf-unless-okay
- vec command "‘%s’ returns with error" command))
+ vec command "`%s' returns with error" command))
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
;; Read the marker.
(error (unless noerror
(tramp-error
vec 'file-error
- "‘%s’ does not return the marker ‘%s’: ‘%s’"
+ "`%s' does not return the marker `%s': `%s'"
command marker (buffer-string))))))
;; Read the expression.
(condition-case nil
(error (unless noerror
(tramp-error
vec 'file-error
- "‘%s’ does not return a valid Lisp expression: ‘%s’"
+ "`%s' does not return a valid Lisp expression: `%s'"
command (buffer-string))))))))
(defun tramp-convert-file-attributes (vec attr)
Convert file mode bits to string and set virtual device number.
Return ATTR."
(when attr
- ;; Convert symlink from `tramp-do-file-attributes-with-stat'.
- (when (consp (car attr))
- (if (and (stringp (caar attr))
- (string-match ".+ -> .\\(.+\\)." (caar attr)))
- (setcar attr (match-string 1 (caar attr)))
- (setcar attr nil)))
- ;; Remove color escape sequences and double slashes from symlink.
+ ;; Remove color escape sequences from symlink.
(when (stringp (car attr))
(while (string-match tramp-color-escape-sequence-regexp (car attr))
- (setcar attr (replace-match "" nil nil (car attr))))
- (while (string-match "//" (car attr))
- (setcar attr (replace-match "/" nil nil (car attr)))))
+ (setcar attr (replace-match "" nil nil (car attr)))))
;; Convert uid and gid. Use -1 as indication of unusable value.
(when (and (numberp (nth 2 attr)) (< (nth 2 attr) 0))
(setcar (nthcdr 2 attr) -1))
;; Convert directory indication bit.
(when (string-match "^d" (nth 8 attr))
(setcar attr t))
+ ;; Convert symlink from `tramp-do-file-attributes-with-stat'.
+ (when (consp (car attr))
+ (if (and (stringp (caar attr))
+ (string-match ".+ -> .\\(.+\\)." (caar attr)))
+ (setcar attr (match-string 1 (caar attr)))
+ (setcar attr nil)))
;; Set file's gid change bit.
(setcar (nthcdr 9 attr)
(if (numberp (nth 3 attr))
(progn
(tramp-message
vec 3
- "‘getconf PATH’ not successful, using default value \"%s\"."
+ "`getconf PATH' not successful, using default value \"%s\"."
"/bin:/usr/bin")
"/bin:/usr/bin"))))
(own-remote-path
;; The login shell could return more than just the $PATH
;; string. So we use `tramp-end-of-heredoc' as marker.
(when elt2
- (tramp-send-command-and-read
- vec
- (format
- "%s %s %s 'echo %s \\\"$PATH\\\"'"
- (tramp-get-method-parameter vec 'tramp-remote-shell)
- (mapconcat
- 'identity
- (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)))))
+ (or
+ (tramp-send-command-and-read
+ vec
+ (format
+ "%s %s %s 'echo %s \\\"$PATH\\\"'"
+ (tramp-get-method-parameter vec 'tramp-remote-shell)
+ (mapconcat
+ 'identity
+ (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))
+ 'noerror (regexp-quote tramp-end-of-heredoc))
+ (progn
+ (tramp-message
+ vec 2 "Could not retrieve `tramp-own-remote-path'")
+ nil)))))
;; Replace place holder `tramp-default-remote-path'.
(when elt1
(defun tramp-get-remote-locale (vec)
(with-tramp-connection-property vec "locale"
(tramp-send-command vec "locale -a")
- (let ((candidates '("en_US.utf8" "C.utf8"))
+ (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8"))
locale)
(with-current-buffer (tramp-get-connection-buffer vec)
(while candidates
(defun tramp-get-ls-command (vec)
(with-tramp-connection-property vec "ls"
- (tramp-message vec 5 "Finding a suitable ‘ls’ command")
+ (tramp-message vec 5 "Finding a suitable `ls' command")
(or
(catch 'ls-found
(dolist (cmd '("ls" "gnuls" "gls"))
(setq result (concat result " --color=never")))
(throw 'ls-found result))
(setq dl (cdr dl))))))
- (tramp-error vec 'file-error "Couldn’t find a proper ‘ls’ command"))))
+ (tramp-error vec 'file-error "Couldn't find a proper `ls' command"))))
(defun tramp-get-ls-command-with-dired (vec)
(save-match-data
(with-tramp-connection-property vec "ls-dired"
- (tramp-message vec 5 "Checking, whether ‘ls --dired’ works")
+ (tramp-message vec 5 "Checking, whether `ls --dired' works")
;; Some "ls" versions are sensible wrt the order of arguments,
;; they fail when "-al" is after the "--dired" argument (for
;; example on FreeBSD).
(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-message vec 5 "Checking, whether `ls --quoting-style=shell' works")
(tramp-send-command-and-check
vec (format "%s --quoting-style=shell -al /dev/null"
(tramp-get-ls-command vec))))))
+(defun tramp-get-ls-command-with-w-option (vec)
+ (save-match-data
+ (with-tramp-connection-property vec "ls-w-option"
+ (tramp-message vec 5 "Checking, whether `ls -w' works")
+ ;; Option "-w" is available on BSD systems. No argument is
+ ;; given, because this could return wrong results in case "ls"
+ ;; supports the "-w NUM" argument, as for busyboxes.
+ (tramp-send-command-and-check
+ vec (format "%s -alw" (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")
+ (tramp-message vec 5 "Finding a suitable `test' command")
(if (tramp-send-command-and-check vec "test 0")
"test"
(tramp-find-executable vec "test" (tramp-get-remote-path vec)))))
(defun tramp-get-remote-ln (vec)
(with-tramp-connection-property vec "ln"
- (tramp-message vec 5 "Finding a suitable ‘ln’ command")
+ (tramp-message vec 5 "Finding a suitable `ln' command")
(tramp-find-executable vec "ln" (tramp-get-remote-path vec))))
(defun tramp-get-remote-perl (vec)
(with-tramp-connection-property vec "perl"
- (tramp-message vec 5 "Finding a suitable ‘perl’ command")
+ (tramp-message vec 5 "Finding a suitable `perl' command")
(let ((result
(or (tramp-find-executable vec "perl5" (tramp-get-remote-path vec))
(tramp-find-executable
(defun tramp-get-remote-stat (vec)
(with-tramp-connection-property vec "stat"
- (tramp-message vec 5 "Finding a suitable ‘stat’ command")
+ (tramp-message vec 5 "Finding a suitable `stat' command")
(let ((result (tramp-find-executable
vec "stat" (tramp-get-remote-path vec)))
tmp)
(defun tramp-get-remote-readlink (vec)
(with-tramp-connection-property vec "readlink"
- (tramp-message vec 5 "Finding a suitable ‘readlink’ command")
+ (tramp-message vec 5 "Finding a suitable `readlink' command")
(let ((result (tramp-find-executable
vec "readlink" (tramp-get-remote-path vec))))
(when (and result
(defun tramp-get-remote-trash (vec)
(with-tramp-connection-property vec "trash"
- (tramp-message vec 5 "Finding a suitable ‘trash’ command")
+ (tramp-message vec 5 "Finding a suitable `trash' command")
(tramp-find-executable vec "trash" (tramp-get-remote-path vec))))
(defun tramp-get-remote-touch (vec)
(with-tramp-connection-property vec "touch"
- (tramp-message vec 5 "Finding a suitable ‘touch’ command")
+ (tramp-message vec 5 "Finding a suitable `touch' command")
(let ((result (tramp-find-executable
vec "touch" (tramp-get-remote-path vec)))
(tmpfile
(defun tramp-get-remote-gvfs-monitor-dir (vec)
(with-tramp-connection-property vec "gvfs-monitor-dir"
- (tramp-message vec 5 "Finding a suitable ‘gvfs-monitor-dir’ command")
+ (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command")
(tramp-find-executable
vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t)))
(defun tramp-get-remote-inotifywait (vec)
(with-tramp-connection-property vec "inotifywait"
- (tramp-message vec 5 "Finding a suitable ‘inotifywait’ command")
+ (tramp-message vec 5 "Finding a suitable `inotifywait' command")
(tramp-find-executable vec "inotifywait" (tramp-get-remote-path vec) t t)))
(defun tramp-get-remote-id (vec)
(with-tramp-connection-property vec "id"
- (tramp-message vec 5 "Finding POSIX ‘id’ command")
+ (tramp-message vec 5 "Finding POSIX `id' command")
(catch 'id-found
(dolist (cmd '("id" "gid"))
(let ((dl (tramp-get-remote-path vec))
(tramp-get-remote-id vec)
(if (equal id-format 'integer) "" "n")
(if (equal id-format 'integer)
- "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/"))))
+ "" "| sed -e s/^/\\\"/ -e s/\\$/\\\"/"))))
(defun tramp-get-remote-uid-with-perl (vec id-format)
(tramp-send-command-and-read
(defun tramp-get-remote-python (vec)
(with-tramp-connection-property vec "python"
- (tramp-message vec 5 "Finding a suitable ‘python’ command")
+ (tramp-message vec 5 "Finding a suitable `python' command")
(or (tramp-find-executable vec "python" (tramp-get-remote-path vec))
(tramp-find-executable vec "python2" (tramp-get-remote-path vec))
(tramp-find-executable vec "python3" (tramp-get-remote-path vec)))))
(tramp-get-remote-id vec)
(if (equal id-format 'integer) "" "n")
(if (equal id-format 'integer)
- "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/"))))
+ "" "| sed -e s/^/\\\"/ -e s/\\$/\\\"/"))))
(defun tramp-get-remote-gid-with-perl (vec id-format)
(tramp-send-command-and-read