;;; 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)
(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 {
;; 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."
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)
- (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)
+ ;; 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)
(current-time)
time))
;; With GNU Emacs, `format-time-string' has an
- ;; optional parameter UNIVERSAL. This is preferred,
+ ;; optional parameter ZONE. This is preferred,
;; because we could handle the case when the remote
;; host is located in a different time zone as the
;; local host.
(narrow-to-region (point) (point))
;; We cannot use `insert-buffer-substring' because the Tramp
;; buffer changes its contents before insertion due to calling
- ;; `expand-file' and alike.
+ ;; `expand-file-name' and alike.
(insert
(with-current-buffer (tramp-get-buffer v)
(buffer-string)))
(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-decode (or (car cs) 'undecided)
+ cs-encode (or (cdr cs) 'undecided))
(setq cs-encode
(tramp-compat-coding-system-change-eol-conversion
cs-encode
(when (search-forward "\r" nil t)
(setq cs-decode (tramp-compat-coding-system-change-eol-conversion
cs-decode 'dos)))
- (tramp-compat-funcall
+ ;; 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))
+ (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))
(when (and p (processp p))
(delete-process p))
(setenv "TERM" tramp-terminal-type)
- (setenv "LC_ALL" "en_US.utf8")
+ (setenv "LC_ALL" (tramp-get-local-locale vec))
(if (stringp tramp-histfile-override)
(setenv "HISTFILE" tramp-histfile-override)
(if tramp-histfile-override
(setenv "HISTSIZE" "0"))))
(setenv "PROMPT_COMMAND")
(setenv "PS1" tramp-initial-end-of-output)
+ (unless (stringp tramp-encoding-shell)
+ (tramp-error vec 'file-error "`tramp-encoding-shell' not set"))
(let* ((target-alist (tramp-compute-multi-hops vec))
;; We will apply `tramp-ssh-controlmaster-options'
;; only for the first hop.
target-alist (cdr target-alist)))
;; Make initial shell settings.
- (tramp-open-connection-setup-interactive-shell p vec)))))
+ (tramp-open-connection-setup-interactive-shell p vec)
+
+ ;; Mark it as connected.
+ (tramp-set-connection-property p "connected" t)))))
;; When the user did interrupt, we must cleanup.
(quit
(save-match-data
(with-tramp-connection-property vec "ls-quoting-style"
(tramp-message vec 5 "Checking, whether `ls --quoting-style=shell' works")
- ;; Some "ls" versions are sensible wrt the order of arguments,
- ;; they fail when "-al" is after the "--dired" argument (for
- ;; example on FreeBSD).
(tramp-send-command-and-check
vec (format "%s --quoting-style=shell -al /dev/null"
(tramp-get-ls-command vec))))))
(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.
+ ;; 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))))))