;; 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 ":"!
+;; IRIX64: /usr/bin
(defcustom tramp-remote-path
'(tramp-default-remote-path "/usr/sbin" "/usr/local/bin"
"/local/bin" "/local/freeware/bin" "/local/gnu/bin"
`("HISTFILE=$HOME/.tramp_history" "HISTSIZE=1" "LC_ALL=C"
,(format "TERM=%s" tramp-terminal-type)
"EMACS=t" ;; Deprecated.
- ,(format "INSIDE_EMACS=%s,tramp:%s" emacs-version tramp-version)
+ ,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
"CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH="
"autocorrect=" "correct=")
(defcustom tramp-shell-prompt-pattern
;; Allow a prompt to start right after a ^M since it indeed would be
- ;; displayed at the beginning of the line (and Zsh uses it).
- "\\(?:^\\|\r\\)[^#$%>\n]*#?[#$%>] *\\(\e\\[[0-9;]*[a-zA-Z] *\\)*"
+ ;; displayed at the beginning of the line (and Zsh uses it). This
+ ;; regexp works only for GNU Emacs.
+ (concat (if (featurep 'xemacs) "" "\\(?:^\\|\r\\)")
+ "[^#$%>\n]*#?[#$%>] *\\(\e\\[[0-9;]*[a-zA-Z] *\\)*")
"Regexp to match prompts from remote shell.
Normally, Tramp expects you to configure `shell-prompt-pattern'
correctly, but sometimes it happens that you are connecting to a
$stat[2],
$stat[1] >> 16 & 0xffff,
$stat[1] & 0xffff
-);' \"$1\" \"$2\" \"$3\" 2>/dev/null"
+);' \"$1\" \"$2\" 2>/dev/null"
"Perl script to produce output suitable for use with `file-attributes'
on the remote file system.
Escape sequence %s is replaced with name of Perl binary.
$stat[0] >> 16 & 0xffff,
$stat[0] & 0xffff);
}
-printf(\")\\n\");' \"$1\" \"$2\" \"$3\" 2>/dev/null"
+printf(\")\\n\");' \"$1\" \"$2\" 2>/dev/null"
"Perl script implementing `directory-files-attributes' as Lisp `read'able
output.
Escape sequence %s is replaced with name of Perl binary.
(setq fn (symbol-name btf))
(unless (and (string-match "^tramp" fn)
(not (string-match
- "^tramp\\(-debug\\)?\\(-message\\|-error\\)$"
+ "^tramp\\(-debug\\)?\\(-message\\|-error\\|-compat-funcall\\)$"
fn)))
(setq fn nil)))
(setq btn (1+ btn))))
(put 'with-connection-property 'edebug-form-spec t)
(font-lock-add-keywords 'emacs-lisp-mode '("\\<with-connection-property\\>"))
+(defun tramp-progress-reporter-update (reporter &optional value)
+ (let* ((parameters (cdr reporter))
+ (message (aref parameters 3)))
+ (when (string-match message (or (current-message) ""))
+ (funcall 'progress-reporter-update reporter value))))
+
(defmacro with-progress-reporter (vec level message &rest body)
- "Executes BODY, spinning a progress reporter with MESSAGE."
+ "Executes BODY, spinning a progress reporter with MESSAGE.
+If LEVEL does not fit for visible messages, or if this is a
+nested call of the macro, there are only traces without a visible
+progress reporter."
`(let (pr tm)
(tramp-message ,vec ,level "%s..." ,message)
;; We start a pulsing progress reporter after 3 seconds. Feature
(<= ,level (min tramp-verbose 3)))
(condition-case nil
(setq pr (tramp-compat-funcall 'make-progress-reporter ,message)
- tm (if pr (run-at-time 3 0.1 'progress-reporter-update pr)))
+ tm (when pr
+ (run-at-time 3 0.1 'tramp-progress-reporter-update pr)))
(error nil)))
(unwind-protect
- ;; Execute the body.
+ ;; Execute the body. Unset `tramp-message-show-message' when
+ ;; the timer object is created, in order to suppress
+ ;; concurrent timers.
(let ((tramp-message-show-message
(and tramp-message-show-message (not tm))))
,@body)
l-localname)))))
(tramp-error
l 'file-already-exists "File %s already exists" l-localname)
- (tramp-compat-delete-file linkname 'force)))
+ (delete-file linkname)))
;; If FILENAME is a Tramp name, use just the localname component.
(when (tramp-tramp-file-p filename)
;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil.
(unwind-protect
(load local-copy noerror t t)
- (tramp-compat-delete-file local-copy 'force)))))
+ (delete-file local-copy)))))
t)))
;; Localname manipulation functions that grok Tramp localnames...
;; Set the mode.
(set-file-modes newname (tramp-default-file-modes filename))
;; If the operation was `rename', delete the original file.
- (unless (eq op 'copy) (tramp-compat-delete-file filename 'force)))
+ (unless (eq op 'copy) (delete-file filename)))
(defun tramp-do-copy-or-rename-file-directly
(op filename newname ok-if-already-exists keep-date preserve-uid-gid)
;; Save exit.
(condition-case nil
- (tramp-compat-delete-file tmpfile 'force)
+ (delete-file tmpfile)
(error)))))))))
;; Set the time and mode. Mask possible errors.
(if dir-flag
(tramp-compat-delete-directory
(expand-file-name ".." tmpfile) 'recursive)
- (tramp-compat-delete-file tmpfile 'force))
+ (delete-file tmpfile))
(error))))
;; Expand hops. Might be necessary for gateway methods.
;; If the operation was `rename', delete the original file.
(unless (eq op 'copy)
(if (file-regular-p filename)
- (tramp-compat-delete-file filename 'force)
+ (delete-file filename)
(tramp-compat-delete-directory filename 'recursive))))))
(defun tramp-handle-make-directory (dir &optional parents)
(tramp-shell-quote-argument localname))))
(tramp-error v 'file-error "Couldn't delete %s" directory))))
-(defun tramp-handle-delete-file (filename &optional force)
+(defun tramp-handle-delete-file (filename &optional trash)
"Like `delete-file' for Tramp files."
(setq filename (expand-file-name filename))
(with-parsed-tramp-file-name filename nil
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname)
- (unless (zerop (tramp-send-command-and-check
- v
- (format "rm -f %s"
- (tramp-shell-quote-argument localname))))
+ (unless
+ (zerop
+ (tramp-send-command-and-check
+ v (format "%s %s"
+ (or (and trash (tramp-get-remote-trash v)) "rm -f")
+ (tramp-shell-quote-argument localname))))
(tramp-error v 'file-error "Couldn't delete %s" filename))))
;; Dired.
(forward-line -2)
(when (looking-at "//SUBDIRED//")
(forward-line -1))
- (when (looking-at "//DIRED//")
- (let ((end (tramp-compat-line-end-position))
- (linebeg (point)))
+ (when (looking-at "//DIRED//\\s-+")
+ (let ((databeg (match-end 0))
+ (end (tramp-compat-line-end-position)))
;; Now read the numeric positions of file names.
- (goto-char linebeg)
- (forward-word 1)
- (forward-char 3)
+ (goto-char databeg)
(while (< (point) end)
(let ((start (+ beg (read (current-buffer))))
(end (+ beg (read (current-buffer)))))
;; Cleanup. We remove all file cache values for the connection,
;; because the remote process could have changed them.
- (when tmpinput (tramp-compat-delete-file tmpinput 'force))
+ (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
(when delete (delete-region start end))
(unwind-protect
(apply 'call-process program tmpfile buffer display args)
- (tramp-compat-delete-file tmpfile 'force))))
+ (delete-file tmpfile))))
(defun tramp-handle-shell-command
(command &optional output-buffer error-buffer)
(let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
;; We cannot use `shell-file-name' and `shell-command-switch',
;; they are variables of the local host.
- (args (list "/bin/sh" "-c" (substring command 0 asynchronous)))
+ (args (list
+ (tramp-get-method-parameter
+ (tramp-file-name-method
+ (tramp-dissect-file-name default-directory))
+ 'tramp-remote-sh)
+ "-c" (substring command 0 asynchronous)))
current-buffer-p
(output-buffer
(cond
(when (listp buffer)
(with-current-buffer error-buffer
(insert-file-contents (cadr buffer)))
- (tramp-compat-delete-file (cadr buffer) 'force))
+ (delete-file (cadr buffer)))
(if current-buffer-p
;; This is like exchange-point-and-mark, but doesn't
;; activate the mark. It is cleaner to avoid activation,
(unwind-protect
(tramp-call-local-coding-command
loc-dec tmpfile2 tmpfile)
- (tramp-compat-delete-file tmpfile2 'force)))))
+ (delete-file tmpfile2)))))
;; Set proper permissions.
(set-file-modes tmpfile (tramp-default-file-modes filename))
;; Error handling.
((error quit)
- (tramp-compat-delete-file tmpfile 'force)
+ (delete-file tmpfile)
(signal (car err) (cdr err))))
(run-hooks 'tramp-handle-file-local-copy-hook)
(set-buffer-modified-p nil))
(when (and (stringp local-copy)
(or remote-copy (null tramp-temp-buffer-file-name)))
- (tramp-compat-delete-file local-copy 'force))
+ (delete-file local-copy))
(when (stringp remote-copy)
- (tramp-compat-delete-file
- (tramp-make-tramp-file-name method user host remote-copy)
- 'force)))))
+ (delete-file
+ (tramp-make-tramp-file-name method user host remote-copy))))))
;; Result.
(list (expand-file-name filename)
(list start end tmpfile append 'no-message lockname confirm))
((error quit)
(setq tramp-temp-buffer-file-name nil)
- (tramp-compat-delete-file tmpfile 'force)
+ (delete-file tmpfile)
(signal (car err) (cdr err))))
;; Now, `last-coding-system-used' has the right value. Remember it.
(copy-file tmpfile filename t)
((error quit)
(setq tramp-temp-buffer-file-name nil)
- (tramp-compat-delete-file tmpfile 'force)
+ (delete-file tmpfile)
(signal (car err) (cdr err)))))
(setq tramp-temp-buffer-file-name nil)
;; Don't rename, in order to keep context in SELinux.
(unwind-protect
(copy-file tmpfile filename t)
- (tramp-compat-delete-file tmpfile 'force))))
+ (delete-file tmpfile))))
;; Use inline file transfer.
(rem-dec
filename rem-dec)))))
;; Save exit.
- (tramp-compat-delete-file tmpfile 'force)))
+ (delete-file tmpfile)))
;; That's not expected.
(t
;; XEmacs only.
'dired-print-file 'dired-shell-call-process
;; nowhere yet.
- 'executable-find 'start-process 'call-process))
+ 'executable-find 'start-process
+ 'call-process 'call-process-region))
default-directory)
;; Unknown file primitive.
(t (error "unknown file I/O primitive: %s" operation))))
(if foreign
(condition-case err
(apply foreign operation args)
+
+ ;; Trace that somebody has interrupted the
+ ;; operation.
+ (quit
+ (let (tramp-message-show-message)
+ (tramp-message
+ v 1 "Interrupt received in operation %s"
+ (append (list operation) args)))
+ ;; Propagate the quit signal.
+ (signal (car err) (cdr err)))
+
+ ;; When we are in completion mode, some failed
+ ;; operations shall return at least a default value
+ ;; in order to give the user a chance to correct the
+ ;; file name in the minibuffer.
(error
(cond
- ;; When we are in completion mode, some failed
- ;; operations shall return at least a default
- ;; value in order to give the user a chance to
- ;; correct the file name in the minibuffer.
((and completion (zerop (length localname))
(memq operation '(file-exists-p file-directory-p)))
t)
filename)
;; Propagate the error.
(t (signal (car err) (cdr err))))))
+
;; Nothing to do for us.
(tramp-run-real-handler operation args)))))
"Remove temporary files related to current buffer."
(when (stringp tramp-temp-buffer-file-name)
(condition-case nil
- (tramp-compat-delete-file tramp-temp-buffer-file-name 'force)
+ (delete-file tramp-temp-buffer-file-name)
(error nil))))
(add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function)
(t (tramp-message
vec 5 "Remote `%s' groks tilde expansion, good"
- (tramp-get-method-parameter
- (tramp-file-name-method vec) 'tramp-remote-sh))
- (tramp-set-connection-property
- vec "remote-shell"
- (tramp-get-method-parameter
- (tramp-file-name-method vec) 'tramp-remote-sh))))))))
+ (tramp-set-connection-property
+ vec "remote-shell"
+ (tramp-get-method-parameter
+ (tramp-file-name-method vec) 'tramp-remote-sh)))))))))
;; ------------------------------------------------------------
;; -- Functions for establishing connection --
(defun tramp-process-actions (proc vec actions &optional timeout)
"Perform actions until success or TIMEOUT."
- ;; Enable auth-source and password-cache.
- (tramp-set-connection-property vec "first-password-request" t)
- (let (exit)
- (while (not exit)
- (tramp-message proc 3 "Waiting for prompts from remote shell")
- (setq exit
- (catch 'tramp-action
- (if timeout
- (with-timeout (timeout)
- (tramp-process-one-action proc vec actions))
- (tramp-process-one-action proc vec actions)))))
- (with-current-buffer (tramp-get-connection-buffer vec)
- (tramp-message vec 6 "\n%s" (buffer-string)))
- (unless (eq exit 'ok)
- (tramp-clear-passwd vec)
- (tramp-error-with-buffer
- nil vec 'file-error
- (cond
- ((eq exit 'permission-denied) "Permission denied")
- ((eq exit 'process-died) "Process died")
- (t "Login failed"))))))
+ ;; Preserve message for `progress-reporter'.
+ (with-temp-message ""
+ ;; Enable auth-source and password-cache.
+ (tramp-set-connection-property vec "first-password-request" t)
+ (let (exit)
+ (while (not exit)
+ (tramp-message proc 3 "Waiting for prompts from remote shell")
+ (setq exit
+ (catch 'tramp-action
+ (if timeout
+ (with-timeout (timeout)
+ (tramp-process-one-action proc vec actions))
+ (tramp-process-one-action proc vec actions)))))
+ (with-current-buffer (tramp-get-connection-buffer vec)
+ (tramp-message vec 6 "\n%s" (buffer-string)))
+ (unless (eq exit 'ok)
+ (tramp-clear-passwd vec)
+ (tramp-error-with-buffer
+ nil vec 'file-error
+ (cond
+ ((eq exit 'permission-denied) "Permission denied")
+ ((eq exit 'process-died) "Process died")
+ (t "Login failed")))))))
;; Utility functions.
;; Disable unexpected output.
(tramp-send-command vec "mesg n; biff n" t)
+ ;; IRIX64 bash expands "!" even when in single quotes. This
+ ;; destroys our shell functions, we must disable it. See
+ ;; <http://stackoverflow.com/questions/3291692/irix-bash-shell-expands-expression-in-single-quotes-yet-shouldnt>.
+ (when (string-match "^IRIX64" (tramp-get-connection-property vec "uname" ""))
+ (tramp-send-command vec "set +H" t))
+
;; Set the environment.
(tramp-message vec 5 "Setting default environment")
(setq env (cdr env)))
(when unset
(tramp-send-command
- vec (format "unset %s" (mapconcat 'identity unset " "))))) t)
+ vec (format "unset %s" (mapconcat 'identity unset " ")) t))))
;; CCC: We should either implement a Perl version of base64 encoding
;; and decoding. Then we just use that in the last item. The other
;; Add arguments for asynchrononous processes.
(when (and process-name async-args)
- (setq login-args (append login-args async-args)))
+ (setq login-args (append async-args login-args)))
;; Add gateway arguments if necessary.
(when (and gw gw-args)
- (setq login-args (append login-args gw-args)))
+ (setq login-args (append gw-args login-args)))
;; Check for port number. Until now, there's no need
;; for handling like method, user, host.
;; Check parameters. On busybox, "ls" output coloring is
;; enabled by default sometimes. So we try to disable it
;; when possible. $LS_COLORING is not supported there.
+ ;; Some "ls" versions are sensible wrt the order of
+ ;; arguments, they fail when "-al" is after the
+ ;; "--color=never" argument (for example on FreeBSD).
(when (zerop (tramp-send-command-and-check
vec (format "%s -lnd /" result)))
(when (zerop (tramp-send-command-and-check
- vec (format "%s --color=never /" result)))
+ vec (format "%s --color=never -al /" result)))
(setq result (concat result " --color=never")))
(throw 'ls-found result))
(setq dl (cdr dl))))))
(save-match-data
(with-connection-property vec "ls-dired"
(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).
(zerop (tramp-send-command-and-check
- vec (format "%s --dired /" (tramp-get-ls-command vec)))))))
+ vec (format "%s --dired -al /" (tramp-get-ls-command vec)))))))
(defun tramp-get-test-command (vec)
(with-connection-property vec "test"
(error nil))))
result))))
+(defun tramp-get-remote-trash (vec)
+ (with-connection-property vec "trash"
+ (tramp-message vec 5 "Finding a suitable `trash' command")
+ (tramp-find-executable vec "trash" (tramp-get-remote-path vec))))
+
(defun tramp-get-remote-id (vec)
(with-connection-property vec "id"
(tramp-message vec 5 "Finding POSIX `id' command")
exiting if process is running."
(if (fboundp 'set-process-query-on-exit-flag)
(tramp-compat-funcall 'set-process-query-on-exit-flag process flag)
- (tramp-compat-funcall 'process-kill-without-query) process flag))
+ (tramp-compat-funcall 'process-kill-without-query process flag)))
;; ------------------------------------------------------------
;; by the files in that directory. Add this here.
;; * Avoid screen blanking when hitting `g' in dired. (Eli Tziperman)
;; * Make ffap.el grok Tramp filenames. (Eli Tziperman)
-;; * Case-insensitive filename completion. (Norbert Goevert.)
;; * Don't use globbing for directories with many files, as this is
;; likely to produce long command lines, and some shells choke on
;; long command lines.
;; rsync).
;; * Keep a second connection open for out-of-band methods like scp or
;; rsync.
-;; * Support ptys in `tramp-handle-start-file-process'. (Bug#4604)
+;; * Support ptys in `tramp-handle-start-file-process'. (Bug#4604, Bug#6360)
;; * IMHO, it's a drawback that currently Tramp doesn't support
;; Unicode in Dired file names by default. Is it possible to
;; improve Tramp to set LC_ALL to "C" only for commands where Tramp
;; without built-in uuencode/uudecode.
;; * Let `shell-dynamic-complete-*' and `comint-dynamic-complete' work
;; on remote hosts.
-;; * Use secrets.el for password handling.
;; * Load ~/.emacs_SHELLNAME on the remote host for `shell'.
;; Functions for file-name-handler-alist: