;;; 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)
(eval-when-compile
(require 'cl)
(require 'dired))
-(defvar directory-sep-char)
(defvar tramp-gw-tunnel-method)
(defvar tramp-gw-socks-method)
(defvar vc-handled-backends)
"///%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
(tramp-remote-shell-args ("-c"))
(tramp-connection-timeout 10)))
;;;###tramp-autoload
+(add-to-list
+ 'tramp-methods
+ '("sg"
+ (tramp-login-program "sg")
+ (tramp-login-args (("-") ("%u")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-c"))
+ (tramp-connection-timeout 10)))
+;;;###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")
(tramp-remote-shell-args ("-c"))
(tramp-copy-program "pscp")
(tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k")
- ("-q") ("-r")))
- (tramp-copy-keep-date t)
- (tramp-copy-recursive t)))
+ ("-q")))
+ (tramp-copy-keep-date t)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("fcp"
'((tramp-parse-passwd "/etc/passwd"))
"Default list of (FUNCTION FILE) pairs to be examined for su methods.")
+;;;###tramp-autoload
+(defconst tramp-completion-function-alist-sg
+ '((tramp-parse-etc-group "/etc/group"))
+ "Default list of (FUNCTION FILE) pairs to be examined for sg methods.")
+
;;;###tramp-autoload
(defconst tramp-completion-function-alist-putty
`((tramp-parse-putty
,(if (memq system-type '(windows-nt))
"HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"
"~/.putty/sessions")))
- "Default list of (FUNCTION REGISTRY) pairs to be examined for putty sessions.")
+ "Default list of (FUNCTION REGISTRY) pairs to be examined for putty sessions.")
;;;###tramp-autoload
(eval-after-load 'tramp
(tramp-set-completion-function "su" tramp-completion-function-alist-su)
(tramp-set-completion-function "sudo" tramp-completion-function-alist-su)
(tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
+ (tramp-set-completion-function "sg" tramp-completion-function-alist-sg)
(tramp-set-completion-function
"krlogin" tramp-completion-function-alist-rsh)
(tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
;; 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'
(defconst tramp-perl-encode
"%s -e '
# This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2015 Free Software Foundation, Inc.
+# Copyright (C) 2002-2016 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-2015 Free Software Foundation, Inc.
+# Copyright (C) 2002-2016 Free Software Foundation, Inc.
use strict;
my %%trans = do {
(directory-files . tramp-handle-directory-files)
(directory-files-and-attributes
. tramp-sh-handle-directory-files-and-attributes)
- ;; `dired-call-process' performed by default handler.
(dired-compress-file . tramp-sh-handle-dired-compress-file)
- (dired-recursive-delete-directory
- . tramp-sh-handle-dired-recursive-delete-directory)
(dired-uncache . tramp-handle-dired-uncache)
(expand-file-name . tramp-sh-handle-expand-file-name)
(file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
(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)
;; `get-file-buffer' performed by default handler.
(insert-directory . tramp-sh-handle-insert-directory)
(insert-file-contents . tramp-handle-insert-file-contents)
- (insert-file-contents-literally
- . tramp-sh-handle-insert-file-contents-literally)
(load . tramp-handle-load)
(make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
(make-directory . tramp-sh-handle-make-directory)
(shell-command . tramp-handle-shell-command)
(start-file-process . tramp-sh-handle-start-file-process)
(substitute-in-file-name . tramp-handle-substitute-in-file-name)
- (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
+ (unhandled-file-name-directory . ignore)
(vc-registered . tramp-sh-handle-vc-registered)
(verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
(write-region . tramp-sh-handle-write-region))
;; Right, they are on the same host, regardless of user, method,
;; etc. We now make the link on the remote machine. This will
;; occur as the user that FILENAME belongs to.
- (tramp-send-command-and-check
- l
- (format
- "cd %s && %s -sf %s %s"
- (tramp-shell-quote-argument cwd)
- ln
- (tramp-shell-quote-argument filename)
- (tramp-shell-quote-argument l-localname))
- t))))
+ (and (tramp-send-command-and-check
+ l (format "cd %s" (tramp-shell-quote-argument cwd)))
+ (tramp-send-command-and-check
+ l (format
+ "%s -sf %s %s"
+ ln
+ (tramp-shell-quote-argument filename)
+ ;; The command could exceed PATH_MAX, so we use
+ ;; relative file names. However, relative file names
+ ;; could start with "-". `tramp-shell-quote-argument'
+ ;; does not handle this, we must do it ourselves.
+ (tramp-shell-quote-argument
+ (concat "./" (file-name-nondirectory l-localname)))))))))
(defun tramp-sh-handle-file-truename (filename)
"Like `file-truename' for Tramp files."
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)
(format "tramp_perl_file_truename %s"
(tramp-shell-quote-argument localname)))))
- ;; 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)
+ ;; Do it yourself.
+ (t (let ((steps (split-string localname "/" 'omit))
+ (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
- (append (tramp-compat-split-string
- symlink-target "/")
- steps)))
+ (append
+ (split-string symlink-target "/" 'omit) steps)))
(t
;; It's a file.
(setq result (cons thisstep result)))))
(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 "/".
res-inode res-filemodes res-numlinks
res-uid res-gid res-size res-symlink-target)
(tramp-message vec 5 "file attributes with ls: %s" localname)
- (tramp-send-command
- vec
- (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 ...
- (with-current-buffer (tramp-get-buffer vec)
- (when (> (buffer-size) 0)
- (goto-char (point-min))
- ;; ... inode
- (setq res-inode
- (condition-case err
- (read (current-buffer))
- (invalid-read-syntax
- (when (and (equal (cadr err)
- "Integer constant overflow in reader")
- (string-match
- "^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
- (car (cddr err))))
- (let* ((big (read (substring (car (cddr err)) 0
- (match-beginning 1))))
- (small (read (match-string 1 (car (cddr err)))))
- (twiddle (/ small 65536)))
- (cons (+ big twiddle)
- (- small (* twiddle 65536))))))))
- ;; ... file mode flags
- (setq res-filemodes (symbol-name (read (current-buffer))))
- ;; ... number links
- (setq res-numlinks (read (current-buffer)))
- ;; ... uid and gid
- (setq res-uid (read (current-buffer)))
- (setq res-gid (read (current-buffer)))
- (if (eq id-format 'integer)
+ ;; We cannot send all three commands combined, it could exceed
+ ;; NAME_MAX or PATH_MAX. Happened on Mac OS X, for example.
+ (when (or (tramp-send-command-and-check
+ vec
+ (format "%s %s"
+ (tramp-get-file-exists-command vec)
+ (tramp-shell-quote-argument localname)))
+ (tramp-send-command-and-check
+ vec
+ (format "%s -h %s"
+ (tramp-get-test-command vec)
+ (tramp-shell-quote-argument localname))))
+ (tramp-send-command
+ vec
+ (format "%s %s %s %s"
+ (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.
+ (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)
+ (when (> (buffer-size) 0)
+ (goto-char (point-min))
+ ;; ... inode
+ (setq res-inode
+ (condition-case err
+ (read (current-buffer))
+ (invalid-read-syntax
+ (when (and (equal (cadr err)
+ "Integer constant overflow in reader")
+ (string-match
+ "^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
+ (car (cddr err))))
+ (let* ((big (read (substring (car (cddr err)) 0
+ (match-beginning 1))))
+ (small (read (match-string 1 (car (cddr err)))))
+ (twiddle (/ small 65536)))
+ (cons (+ big twiddle)
+ (- small (* twiddle 65536))))))))
+ ;; ... file mode flags
+ (setq res-filemodes (symbol-name (read (current-buffer))))
+ ;; ... number links
+ (setq res-numlinks (read (current-buffer)))
+ ;; ... uid and gid
+ (setq res-uid (read (current-buffer)))
+ (setq res-gid (read (current-buffer)))
+ (if (eq id-format 'integer)
+ (progn
+ (unless (numberp res-uid) (setq res-uid -1))
+ (unless (numberp res-gid) (setq res-gid -1)))
(progn
- (unless (numberp res-uid) (setq res-uid -1))
- (unless (numberp res-gid) (setq res-gid -1)))
- (progn
- (unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
- (unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
- ;; ... size
- (setq res-size (read (current-buffer)))
- ;; 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.
- (when symlinkp
- (search-forward "-> ")
- (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.
- (or dirp res-symlink-target)
- ;; 1. Number of links to file.
- res-numlinks
- ;; 2. File uid.
- res-uid
- ;; 3. File gid.
- res-gid
- ;; 4. Last access time, as a list of integers. Normally this
- ;; would be in the same format as `current-time', but the
- ;; subseconds part is not currently implemented, and (0 0)
- ;; denotes an unknown time.
- ;; 5. Last modification time, likewise.
- ;; 6. Last status change time, likewise.
- '(0 0) '(0 0) '(0 0) ;CCC how to find out?
- ;; 7. Size in bytes (-1, if number is out of range).
- res-size
- ;; 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'.
- t
- ;; 10. Inode number.
- res-inode
- ;; 11. Device number. Will be replaced by a virtual device number.
- -1
- )))))
+ (unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
+ (unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
+ ;; ... size
+ (setq res-size (read (current-buffer)))
+ ;; 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.
+ (when symlinkp
+ (search-forward "-> ")
+ (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.
+ (or dirp res-symlink-target)
+ ;; 1. Number of links to file.
+ res-numlinks
+ ;; 2. File uid.
+ res-uid
+ ;; 3. File gid.
+ res-gid
+ ;; 4. Last access time, as a list of integers. Normally
+ ;; this would be in the same format as `current-time', but
+ ;; the subseconds part is not currently implemented, and
+ ;; (0 0) denotes an unknown time.
+ ;; 5. Last modification time, likewise.
+ ;; 6. Last status change time, likewise.
+ '(0 0) '(0 0) '(0 0) ;CCC how to find out?
+ ;; 7. Size in bytes (-1, if number is out of range).
+ res-size
+ ;; 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'.
+ t
+ ;; 10. Inode number.
+ res-inode
+ ;; 11. Device number. Will be replaced by a virtual device number.
+ -1))))))
(defun tramp-do-file-attributes-with-perl
(vec localname &optional id-format)
(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))
(attr (file-attributes f))
;; '(-1 65535) means file doesn't exists yet.
(modtime (or (nth 5 attr) '(-1 65535))))
- (when (boundp 'last-coding-system-used)
- (setq coding-system-used (symbol-value 'last-coding-system-used)))
+ (setq coding-system-used last-coding-system-used)
;; We use '(0 0) as a don't-know value. See also
;; `tramp-do-file-attributes-with-ls'.
(if (not (equal modtime '(0 0)))
(setq attr (buffer-substring (point) (point-at-eol))))
(tramp-set-file-property
v localname "visited-file-modtime-ild" attr))
- (when (boundp 'last-coding-system-used)
- (set 'last-coding-system-used coding-system-used))
+ (setq last-coding-system-used coding-system-used)
nil)))))
;; This function makes the same assumption as
;; connection.
(if (or (not f)
(eq (visited-file-modtime) 0)
- (not (tramp-file-name-handler 'file-remote-p f nil 'connected)))
+ (not (file-remote-p f nil 'connected)))
t
(with-parsed-tramp-file-name f nil
(let* ((remote-file-name-inhibit-cache t)
;; FIXME: extract the proper text from chmod's stderr.
(tramp-barf-unless-okay
v
- (format "chmod %s %s"
- (tramp-compat-decimal-to-octal mode)
- (tramp-shell-quote-argument localname))
- "Error while changing file’s mode %s" filename)))
+ (format "chmod %o %s" mode (tramp-shell-quote-argument localname))
+ "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."
- (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)
- time))
- ;; With GNU Emacs, `format-time-string' has an
- ;; optional parameter UNIVERSAL. This is preferred,
- ;; because we could handle the case when the remote
- ;; host is located in a different time zone as the
- ;; local host.
- (utc (not (featurep 'xemacs))))
- (tramp-send-command-and-check
- v (format
- "%s %s %s %s"
- (if utc "env TZ=UTC" "")
- (tramp-get-remote-touch v)
- (if (tramp-get-connection-property v "touch-t" nil)
- (format "-t %s"
- (if utc
- (format-time-string "%Y%m%d%H%M.%S" time t)
- (format-time-string "%Y%m%d%H%M.%S" time)))
- "")
- (tramp-shell-quote-argument localname))))))
-
- ;; We handle also the local part, because in older Emacsen,
- ;; without `set-file-times', this function is an alias for this.
- ;; We are local, so we don't need the UTC settings.
- (zerop
- (tramp-call-process
- nil "touch" nil nil nil "-t"
- (format-time-string "%Y%m%d%H%M.%S" time)
- (tramp-shell-quote-argument 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)
+ time)))
+ (tramp-send-command-and-check
+ v (format
+ "env TZ=UTC %s %s %s"
+ (tramp-get-remote-touch v)
+ (if (tramp-get-connection-property v "touch-t" nil)
+ (format "-t %s" (format-time-string "%Y%m%d%H%M.%S" time t))
+ "")
+ (tramp-shell-quote-argument localname)))))))
(defun tramp-set-file-uid-gid (filename &optional uid gid)
"Set the ownership for FILENAME.
(goto-char (point-max))
(delete-blank-lines)
(when (> (point-max) (point-min))
- (tramp-compat-funcall
- 'substring-no-properties (buffer-string))))))))
+ (substring-no-properties (buffer-string))))))))
(defun tramp-sh-handle-set-file-acl (filename acl-string)
"Like `set-file-acl' 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
(when cache-hit (list cache-hit))))
;; We cannot use a length of 0, because file properties
;; for "foo" and "foo/" are identical.
- (tramp-compat-number-sequence (length filename) 1 -1)))))
+ (number-sequence (length filename) 1 -1)))))
;; Cache expired or no matching cache entry found so we need
;; to perform a remote operation.
(format "tramp_perl_file_name_all_completions %s %s %d"
(tramp-shell-quote-argument localname)
(tramp-shell-quote-argument filename)
- (if (symbol-value
- ;; `read-file-name-completion-ignore-case'
- ;; is introduced with Emacs 22.1.
- (if (boundp
- 'read-file-name-completion-ignore-case)
- 'read-file-name-completion-ignore-case
- 'completion-ignore-case))
- 1 0)))
+ (if read-file-name-completion-ignore-case 1 0)))
(format (concat
"(cd %s 2>&1 && (%s -a %s 2>/dev/null"
(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
(tramp-do-copy-or-rename-file
'copy filename newname ok-if-already-exists keep-date
preserve-uid-gid preserve-extended-attributes))
- ;; Compat section.
+ ;; Compat section. PRESERVE-EXTENDED-ATTRIBUTES has been
+ ;; introduced with Emacs 24.1 (as PRESERVE-SELINUX-CONTEXT), and
+ ;; renamed in Emacs 24.3.
(preserve-extended-attributes
(tramp-run-real-handler
'copy-file
(list filename newname ok-if-already-exists keep-date
preserve-uid-gid preserve-extended-attributes)))
- (preserve-uid-gid
- (tramp-run-real-handler
- 'copy-file
- (list filename newname ok-if-already-exists keep-date preserve-uid-gid)))
(t
(tramp-run-real-handler
- 'copy-file (list filename newname ok-if-already-exists keep-date)))))
+ 'copy-file
+ (list filename newname ok-if-already-exists keep-date preserve-uid-gid)))))
(defun tramp-sh-handle-copy-directory
(dirname newname &optional keep-date parents copy-contents)
(if (or (tramp-tramp-file-p filename)
(tramp-tramp-file-p newname))
(tramp-do-copy-or-rename-file
- 'rename filename newname ok-if-already-exists t t)
+ 'rename filename newname ok-if-already-exists
+ 'keep-time 'preserve-uid-gid)
(tramp-run-real-handler
'rename-file (list filename newname ok-if-already-exists))))
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
- (tramp-file-name-handler 'file-remote-p filename 'localname)
+ (file-remote-p filename 'localname)
filename))
(localname2
(if t2
- (tramp-file-name-handler 'file-remote-p newname 'localname)
+ (file-remote-p newname 'localname)
newname))
(prefix (file-remote-p (if t1 filename newname)))
cmd-result)
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.
(zerop
(logand
(file-modes (file-name-directory localname1))
- (tramp-compat-octal-to-decimal "1000"))))
+ (string-to-number "1000" 8))))
(file-writable-p (file-name-directory localname2))
(or (file-directory-p localname2)
(file-writable-p localname2))))
(if (eq op 'copy)
- (tramp-compat-copy-file
+ (copy-file
localname1 localname2 ok-if-already-exists
keep-date preserve-uid-gid)
(tramp-run-real-handler
"%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
;; give read permissions.
(set-file-modes
- (concat prefix tmpfile)
- (tramp-compat-octal-to-decimal "0777"))
+ (concat prefix tmpfile) (string-to-number "0777" 8))
(tramp-set-file-uid-gid
(concat prefix tmpfile)
(tramp-get-local-uid 'integer)
(tramp-get-local-gid 'integer)))
(t2
(if (eq op 'copy)
- (tramp-compat-copy-file
+ (copy-file
localname1 tmpfile t
keep-date preserve-uid-gid)
(tramp-run-real-handler
;; We must change the ownership as local user.
;; Since this does not work reliable, we also
;; give read permissions.
- (set-file-modes
- tmpfile (tramp-compat-octal-to-decimal "0777"))
+ (set-file-modes tmpfile (string-to-number "0777" 8))
(tramp-set-file-uid-gid
tmpfile
(tramp-get-remote-uid v 'integer)
"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
;; Save exit.
(ignore-errors
(if dir-flag
- (tramp-compat-delete-directory
+ (delete-directory
(expand-file-name ".." tmpfile) 'recursive)
(delete-file tmpfile)))))
(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))
orig-vec 6 "%s"
(mapconcat 'identity (process-command p) " "))
(tramp-set-connection-property p "vector" orig-vec)
- (tramp-compat-set-process-query-on-exit-flag p nil)
+ (set-process-query-on-exit-flag p nil)
;; We must adapt `tramp-local-end-of-line' for
;; sending the password.
(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.
(unless (eq op 'copy)
(if (file-regular-p filename)
(delete-file filename)
- (tramp-compat-delete-directory filename 'recursive))))))
+ (delete-directory filename 'recursive))))))
(defun tramp-sh-handle-make-directory (dir &optional parents)
"Like `make-directory' for Tramp files."
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.
-;; CCC: This does not seem to be enough. Something dies when
-;; we try and delete two directories under Tramp :/
-(defun tramp-sh-handle-dired-recursive-delete-directory (filename)
- "Recursively delete the directory given.
-This is like `dired-recursive-delete-directory' for Tramp files."
- (with-parsed-tramp-file-name filename nil
- ;; Run a shell command 'rm -r <localname>'.
- ;; Code shamelessly stolen from the dired implementation and, um, hacked :)
- (unless (file-exists-p filename)
- (tramp-error v 'file-error "No such directory: %s" filename))
- ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>).
- (tramp-send-command
- v
- (format "rm -rf %s" (tramp-shell-quote-argument localname))
- ;; Don't read the output, do it explicitly.
- nil t)
- ;; Wait for the remote system to return to us...
- ;; This might take a while, allow it plenty of time.
- (tramp-wait-for-output (tramp-get-connection-process v) 120)
- ;; Make sure that it worked...
- (tramp-flush-file-property v (file-name-directory localname))
- (tramp-flush-directory-property v localname)
- (and (file-exists-p filename)
- (tramp-error
- v 'file-error "Failed to recursively delete %s" filename))))
+(defvar dired-compress-file-suffixes)
+(declare-function dired-remove-file "dired-aux")
-(defun tramp-sh-handle-dired-compress-file (file &rest _ok-flag)
+(defun tramp-sh-handle-dired-compress-file (file)
"Like `dired-compress-file' for Tramp files."
- ;; OK-FLAG is valid for XEmacs only, but not implemented.
;; Code stolen mainly from dired-aux.el.
(with-parsed-tramp-file-name file nil
(tramp-flush-file-property v localname)
(save-excursion
- (let ((suffixes
- (if (not (featurep 'xemacs))
- ;; Emacs case
- (symbol-value 'dired-compress-file-suffixes)
- ;; XEmacs has `dired-compression-method-alist', which is
- ;; transformed into `dired-compress-file-suffixes' structure.
- (mapcar
- (lambda (x)
- (list (concat (regexp-quote (nth 1 x)) "\\'")
- nil
- (mapconcat 'identity (nth 3 x) " ")))
- (symbol-value 'dired-compression-method-alist))))
+ (let ((suffixes dired-compress-file-suffixes)
suffix)
;; See if any suffix rule matches this file name.
(while suffixes
(when (tramp-send-command-and-check
v (concat (nth 2 suffix) " "
(tramp-shell-quote-argument localname)))
- ;; `dired-remove-file' is not defined in XEmacs.
- (tramp-compat-funcall 'dired-remove-file file)
+ (dired-remove-file file)
(string-match (car suffix) file)
(concat (substring file 0 (match-beginning 0))))))
(t
(when (tramp-send-command-and-check
v (concat "gzip -f "
(tramp-shell-quote-argument localname)))
- ;; `dired-remove-file' is not defined in XEmacs.
- (tramp-compat-funcall 'dired-remove-file file)
+ (dired-remove-file file)
(cond ((file-exists-p (concat file ".gz"))
(concat file ".gz"))
((file-exists-p (concat file ".z"))
(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
;; Decode the output, it could be multibyte.
(decode-coding-region
beg (point-max)
- (or file-name-coding-system
- (and (boundp 'default-file-name-coding-system)
- (symbol-value 'default-file-name-coding-system))))
+ (or file-name-coding-system default-file-name-coding-system))
;; The inserted file could be from somewhere else.
(when (and (not wildcard) (not full-directory-p))
(while (string-match "//" localname)
(setq localname (replace-match "/" t t localname)))
;; No tilde characters in file name, do normal
- ;; `expand-file-name' (this does "/./" and "/../"). We bind
- ;; `directory-sep-char' here for XEmacs on Windows, which would
- ;; otherwise use backslash. `default-directory' is bound,
- ;; because on Windows there would be problems with UNC shares or
- ;; Cygwin mounts.
- (let ((directory-sep-char ?/)
- (default-directory (tramp-compat-temporary-file-directory)))
+ ;; `expand-file-name' (this does "/./" and "/../").
+ ;; `default-directory' is bound, because on Windows there would
+ ;; be problems with UNC shares or Cygwin mounts.
+ (let ((default-directory (tramp-compat-temporary-file-directory)))
(tramp-make-tramp-file-name
method user host
(tramp-drop-volume-letter
(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 "")))))
;; Send the command.
(tramp-send-command v command nil t) ; nooutput
;; Check, whether a pty is associated.
- (unless (tramp-compat-process-get
+ (unless (process-get
(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
;; could have finished already.
(ignore-errors
- (tramp-compat-set-process-query-on-exit-flag p t)
+ (set-process-query-on-exit-flag p t)
(set-marker (process-mark p) (point)))
;; Return process.
p))))
;; because the remote process could have changed them.
(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
- ;; by `program'. If it doesn't exist, we assume its default
- ;; value t.
- (unless (and (boundp 'process-file-side-effects)
- (not (symbol-value 'process-file-side-effects)))
+ (unless process-file-side-effects
(tramp-flush-directory-property v ""))
;; Return exit status.
(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))
;; `copy-file' handles direct copy and out-of-band methods.
((or (tramp-local-host-p v)
(tramp-method-out-of-band-p v size))
- (copy-file filename tmpfile t t))
+ (copy-file filename tmpfile 'ok-if-already-exists 'keep-time))
;; Use inline encoding for file transfer.
(rem-enc
(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)
(run-hooks 'tramp-handle-file-local-copy-hook)
tmpfile)))
-;; This is needed for XEmacs only. Code stolen from files.el.
-(defun tramp-sh-handle-insert-file-contents-literally
- (filename &optional visit beg end replace)
- "Like `insert-file-contents-literally' for Tramp files."
- (let ((format-alist nil)
- (after-insert-file-functions nil)
- (coding-system-for-read 'no-conversion)
- (coding-system-for-write 'no-conversion)
- (find-buffer-file-type-function
- (if (fboundp 'find-buffer-file-type)
- (symbol-function 'find-buffer-file-type)
- nil))
- (inhibit-file-name-handlers
- '(epa-file-handler image-file-handler jka-compr-handler))
- (inhibit-file-name-operation 'insert-file-contents))
- (unwind-protect
- (progn
- (fset 'find-buffer-file-type (lambda (_filename) t))
- (insert-file-contents filename visit beg end replace))
- ;; Save exit.
- (if find-buffer-file-type-function
- (fset 'find-buffer-file-type find-buffer-file-type-function)
- (fmakunbound 'find-buffer-file-type)))))
-
;; CCC grok LOCKNAME
(defun tramp-sh-handle-write-region
(start end filename &optional append visit lockname confirm)
;; (error
;; "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME"))
- ;; XEmacs takes a coding system as the seventh argument, not `confirm'.
- (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename))
+ (when (and confirm (file-exists-p filename))
(unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
(tramp-error v 'file-error "File not overwritten")))
- (let ((uid (or (nth 2 (tramp-compat-file-attributes filename 'integer))
+ (let ((uid (or (nth 2 (file-attributes filename 'integer))
(tramp-get-remote-uid v 'integer)))
- (gid (or (nth 3 (tramp-compat-file-attributes filename 'integer))
+ (gid (or (nth 3 (file-attributes filename 'integer))
(tramp-get-remote-gid v 'integer))))
(if (and (tramp-local-host-p v)
(signal (car err) (cdr err))))
;; Now, `last-coding-system-used' has the right value. Remember it.
- (when (boundp 'last-coding-system-used)
- (setq coding-system-used
- (symbol-value 'last-coding-system-used))))
+ (setq coding-system-used last-coding-system-used))
;; The permissions of the temporary file should be set. If
;; FILENAME does not exist (eq modes nil) it has been
(when modes
(set-file-modes
tmpfile
- (logior (or modes 0) (tramp-compat-octal-to-decimal "0400"))))
+ (logior (or modes 0) (string-to-number "0400" 8))))
;; This is a bit lengthy due to the different methods
;; possible for file transfer. First, we check whether the
;; 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))))
(let (last-coding-system-used (need-chown t))
;; Set file modification time.
(when (or (eq visit t) (stringp visit))
- (let ((file-attr (tramp-compat-file-attributes filename 'integer)))
+ (let ((file-attr (file-attributes filename 'integer)))
(set-visited-file-modtime
;; We must pass modtime explicitly, because FILENAME can
;; be different from (buffer-file-name), f.e. if
;; any other remote command.
(defun tramp-sh-handle-vc-registered (file)
"Like `vc-registered' for Tramp files."
- (tramp-compat-with-temp-message ""
+ (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)
- (tramp-compat-set-process-query-on-exit-flag p nil)
+ ;; Needed for `tramp-sh-gvfs-monitor-dir-process-filter'.
+ (process-put p 'events events)
+ (process-put p 'watch-name localname)
+ (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)))
- (rest-string (tramp-compat-process-get proc 'rest-string)))
+ (rest-string (process-get proc 'rest-string)))
(when rest-string
(tramp-message proc 10 "Previous string:\n%s" rest-string))
(tramp-message proc 6 "%S\n%s" proc string)
(setq string (concat rest-string string)
;; Attribute change is returned in unused wording.
- string (tramp-compat-replace-regexp-in-string
+ string (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
+ (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 (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) (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)))
+ (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))
+ (dolist (line (split-string string "[\n\r]+" 'omit))
;; Check, whether there is a problem.
(unless
(string-match
(mapcar
(lambda (x)
(intern-soft
- (tramp-compat-replace-regexp-in-string "_" "-" (downcase x))))
- (split-string (match-string 1 line) "," 'omit-nulls))
+ (replace-regexp-in-string "_" "-" (downcase x))))
+ (split-string (match-string 1 line) "," 'omit))
(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
+ (setq script (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)
(setq result (concat "\\" progname))))
(unless result
(when ignore-tilde
- ;; Remove all ~/foo directories from dirlist. In XEmacs,
- ;; `remove' is in CL, and we want to avoid CL dependencies.
+ ;; Remove all ~/foo directories from dirlist.
(let (newdl d)
(while dirlist
(setq d (car dirlist))
(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)
+ (process-coding-system proc)
(cons 'undecided 'undecided)))
cs-decode cs-encode)
(when (symbolp cs) (setq cs (cons cs cs)))
- (setq cs-decode (car cs))
- (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-decode (or (car cs) 'undecided)
+ cs-encode (or (cdr cs) 'undecided))
+ (setq cs-encode
+ (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)
- (setq cs-decode (tramp-compat-coding-system-change-eol-conversion
+ (setq cs-decode (coding-system-change-eol-conversion
cs-decode 'dos)))
- (tramp-compat-funcall
- 'set-buffer-process-coding-system cs-decode cs-encode)
+ ;; Special setting for Mac OS X.
+ (when (and (string-match
+ "^Darwin" (tramp-get-connection-property vec "uname" ""))
+ (memq 'utf-8-hfs (coding-system-list)))
+ (setq cs-decode 'utf-8-hfs
+ cs-encode 'utf-8-hfs))
+ (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))
- (tramp-compat-process-put proc 'remote-tty tty)))
+ (process-put proc 'remote-tty tty)))
;; Dump stty settings in the traces.
(when (>= tramp-verbose 9)
(copy-sequence tramp-remote-process-environment)))
unset vars item)
(while env
- (setq item (tramp-compat-split-string (car env) "="))
+ (setq item (split-string (car env) "=" 'omit))
(setcdr item (mapconcat 'identity (cdr item) "="))
(if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
(push (format "%s %s" (car item) (cdr item)) vars)
"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))
value
(format-spec-make
?t
- (tramp-file-name-handler
- 'file-remote-p tmpfile 'localname)))))
+ (file-remote-p tmpfile 'localname)))))
(tramp-maybe-send-script vec value name)
(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-file-name-method hop) (tramp-file-name-user hop)
- (tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil nil)
+ (tramp-gw-open-connection vec gw hop) nil nil)
target-alist)
;; For the password prompt, we need the correct values.
;; Therefore, we must remember the gateway vector. But we
(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.
(unless (and p (processp p) (memq (process-status p) '(run open)))
;; If `non-essential' is non-nil, don't reopen a new connection.
+ ;; This variable has been introduced with Emacs 24.1.
(when (and (boundp 'non-essential) (symbol-value 'non-essential))
(throw 'non-essential 'non-essential))
;; Set sentinel and query flag.
(tramp-set-connection-property p "vector" vec)
(set-process-sentinel p 'tramp-process-sentinel)
- (tramp-compat-set-process-query-on-exit-flag p nil)
+ (set-process-query-on-exit-flag p nil)
(setq tramp-current-connection
(cons (butlast (append vec nil) 2) (current-time))
tramp-current-host (system-name))
;; 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))
(when (and (floatp (nth 2 attr))
- (<= (nth 2 attr) (tramp-compat-most-positive-fixnum)))
+ (<= (nth 2 attr) most-positive-fixnum))
(setcar (nthcdr 2 attr) (round (nth 2 attr))))
(when (and (numberp (nth 3 attr)) (< (nth 3 attr) 0))
(setcar (nthcdr 3 attr) -1))
(when (and (floatp (nth 3 attr))
- (<= (nth 3 attr) (tramp-compat-most-positive-fixnum)))
+ (<= (nth 3 attr) most-positive-fixnum))
(setcar (nthcdr 3 attr) (round (nth 3 attr))))
;; Convert last access time.
(unless (listp (nth 4 attr))
(when (< (nth 7 attr) 0)
(setcar (nthcdr 7 attr) -1))
(when (and (floatp (nth 7 attr))
- (<= (nth 7 attr) (tramp-compat-most-positive-fixnum)))
+ (<= (nth 7 attr) most-positive-fixnum))
(setcar (nthcdr 7 attr) (round (nth 7 attr))))
;; Convert file mode bits to string.
(unless (stringp (nth 8 attr))
;; 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
(setcdr elt1
(append
- (tramp-compat-split-string (or default-remote-path "") ":")
+ (split-string (or default-remote-path "") ":" 'omit)
(cdr elt1)))
(setq remote-path (delq 'tramp-default-remote-path remote-path)))
(when elt2
(setcdr elt2
(append
- (tramp-compat-split-string (or own-remote-path "") ":")
+ (split-string (or own-remote-path "") ":" 'omit)
(cdr elt2)))
(setq remote-path (delq 'tramp-own-remote-path remote-path)))
(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
"%s -t %s %s"
result
(format-time-string "%Y%m%d%H%M.%S")
- (tramp-file-name-handler 'file-remote-p tmpfile 'localname))))
+ (file-remote-p tmpfile 'localname))))
(delete-file tmpfile))
result)))
(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
;; rsync).
;; * Keep a second connection open for out-of-band methods like scp or
;; rsync.
+;; * Check, whether we could also use "getent passwd" and "getent
+;; group" for user/group name completion.
;;; tramp-sh.el ends here