Sync with Tramp 2.2.6-pre.

* net/tramp-cache.el (tramp-dump-connection-properties): Let-bind
  `print-length' and `print-level' to nil, in order to avoid
  truncation.  Reported by Christopher Schmidt
  <christopher@ristopher.com>.

* net/tramp-cmds.el (tramp-cleanup-connection): Delete also
process.

* net/tramp-compat.el (tramp-compat-condition-case-unless-debug):
New defmacro.
(tramp-compat-copy-directory): Add optional argument
COPY-CONTENTS.  It is not handled yet.

* net/tramp-ftp.el (tramp-disable-ange-ftp): Fix docstring.
(tramp-ftp-file-name-p): Simplify.

* net/tramp-gvfs.el (tramp-gvfs-handle-expand-file-name):
* net/tramp-gw.el (tramp-gw-open-connection): Add hop to
connection vector.

* net/tramp-sh.el (tramp-copy-size-limit): Fix docstring.
(tramp-methods): Do not use `tramp-password-end-of-line'.
(tramp-completion-function-alist-putty): Handle
UNIX case.
(tramp-remote-path): Add "/opt/bin", "/opt/sbin"
and "/opt/local/bin".
(tramp-do-file-attributes-with-stat)
(tramp-do-directory-files-and-attributes-with-stat)
Return uid and gid as real numbers.  They could run out of
integer range on cygwin.
(tramp-do-copy-or-rename-file-out-of-band): Better
trace format.
(tramp-sh-handle-expand-file-name): Handle hops.
(tramp-open-connection-setup-interactive-shell):
Use `tramp-cleanup'.  Move check for busyboxes ...
(tramp-find-shell): ... here.  Simplify
implementation.  Set "remote-shell" property also for alternative
shells.
(tramp-remote-coding-commands): Check "test -c
/dev/stdout".  If failing, a regular file would be written
otherwise.  Reported by
Dmitry Kurochkin <dmitry.kurochkin@gmail.com>.
(tramp-find-inline-encoding): Cache the coding
commands in the process cache.  Apply test command on the remote
side, if defined.
(tramp-find-inline-compress): Cache the compress
commands in the process cache.
(tramp-compute-multi-hops): Save
`tramp-default-proxies-alist'
when requested.  Handle hops.
(tramp-current-connection): New defvar.
(tramp-maybe-open-connection): Use
`tramp-cleanup'.  Throw
`suppress', if there was a failed connection
shortly before.  Handle user interrupt.  (Bug#10187)
(tramp-get-inline-compress,
tramp-get-inline-coding): Read
connection properties from the process cache.

* net/tramp-smb.el (tramp-smb-server-version)
(tramp-smb-wrong-passwd-regexp,
tramp-smb-actions-with-tar): New defconsts.
(tramp-smb-prompt): Extend for powershell prompt.
(tramp-smb-file-name-handler-alist): Add handlers for
`process-file', `shell-command' and
`start-file-process'.
(tramp-smb-winexe-program, tramp-smb-winexe-shell-command)
(tramp-smb-winexe-shell-command-switch): New
defcustoms.
(tramp-smb-file-name-p): Simplify.
(tramp-smb-action-with-tar,
tramp-smb-handle-process-file)
(tramp-smb-kill-winexe-function, tramp-smb-call-winexe)
(tramp-smb-shell-quote-argument): New defuns.
(tramp-smb-handle-copy-directory): Add
COPY-CONTENTS argument.
Implement using "tar".  By this, time-stamps are
preserved.
(tramp-smb-handle-copy-file): Handle also the case
of directories.
(tramp-smb-do-file-attributes-with-stat)
(tramp-smb-get-file-entries,
tramp-smb-get-cifs-capabilities): Use
`tramp-get-connection-buffer').
(tramp-smb-handle-rename-file): Use "rename", when source and
target are on the same share.
(tramp-smb-maybe-open-connection): Handle wrong passwords.  Use
`tramp-smb-server-version'.
(tramp-smb-wait-for-output): Remove prompt.

* net/tramp.el (top): Require 'cl.
(tramp-methods, tramp-rsh-end-of-line): Remove
`tramp-password-end-of-line' from docstring.
(tramp-save-ad-hoc-proxies): New defcustom.
(tramp-completion-function-alist): Adapt docstring.
(tramp-default-password-end-of-line): Remove defcustom.
(tramp-shell-prompt-pattern): Allow "[]" style
prompts.  (Bug#11065)
(tramp-user-regexp, tramp-file-name-regexp-unified)
(tramp-file-name-regexp-url): Extend regexp by hop
separator.
(tramp-postfix-hop-format,
tramp-postfix-hop-regexp) 
(tramp-remote-file-name-spec-regexp): New defconst.
(tramp-file-name-structure): Extend structure for
hops.
(tramp-get-method-parameter): Move up.
(tramp-file-name-p, tramp-dissect-file-name)
(with-parsed-tramp-file-name): Handle hops.
(tramp-file-name-hop): New defun.
(tramp-make-tramp-file-name): New optional arg HOP.
(tramp-message-show-progress-reporter-message):
New defvar.
(tramp-with-progress-reporter): Use it.  We cannot use
`tramp-message-show-message' here, because this
suppresses also error buffers.
(tramp-error-with-buffer): Suppress buffer view, if
`tramp-message-show-message' is nil.  Use
`tramp-get-connection-buffer'.
(tramp-cleanup): New defun.
(tramp-rfn-eshadow-update-overlay): Let-bind
`non-essential' to `t'.
(tramp-file-name-handler): If `debug-on-error' is
set, propagate an error unchanged.
(tramp-completion-handle-file-name-all-completions):
Handle hops.  Fix an error when called from ido.
(tramp-completion-dissect-file-name): Use better
local variable name.  Add hop to the vector.
(tramp-handle-insert-file-contents): Use
progress-reporter for the whole scenario.
(tramp-action-password): Let-bind
`enable-recursive-minibuffers' to `t'.
(tramp-check-for-regexp): Simplify search.
(tramp-enter-password): Remove it.  Move
implementation ...
(tramp-action-password): ... here.
(tramp-mode-string-to-int, tramp-local-host-p)
(tramp-make-tramp-temp-file, tramp-read-passwd)
(tramp-clear-passwd, tramp-time-less-p,
tramp-time-diff): Set tramp-autoload cookie.

* net/trampver.el: Update release number.

* net/tramp.el (tramp-set-completion-function): Fix
docstring.
(tramp-parse-group, tramp-parse-file)
(tramp-parse-shostkeys-sknownhosts): New defuns.
(tramp-parse-rhosts, tramp-parse-rhosts-group, tramp-parse-shosts)
(tramp-parse-shosts-group, tramp-parse-sconfig)
(tramp-parse-sconfig-group, tramp-parse-shostkeys)
(tramp-parse-sknownhosts, tramp-parse-hosts)
(tramp-parse-hosts-group, tramp-parse-passwd,
tramp-parse-netrc): Use them.
(tramp-parse-passwd-group, tramp-parse-netrc-group)
(tramp-parse-putty-group): Don't narrow.
(tramp-parse-putty): Make a loop.
(tramp-file-name-handler): Catch the `suppress'
signal.
This commit is contained in:
Michael Albinus 2012-06-11 12:30:07 +02:00
parent 72834e10a6
commit 2fe4b1254d
11 changed files with 1211 additions and 648 deletions

View file

@ -1,3 +1,142 @@
2012-06-11 Michael Albinus <michael.albinus@gmx.de>
Sync with Tramp 2.2.6-pre.
* net/tramp-cache.el (tramp-dump-connection-properties): Let-bind
`print-length' and `print-level' to nil, in order to avoid
truncation. Reported by Christopher Schmidt
<christopher@ristopher.com>.
* net/tramp-cmds.el (tramp-cleanup-connection): Delete also process.
* net/tramp-compat.el (tramp-compat-condition-case-unless-debug):
New defmacro.
(tramp-compat-copy-directory): Add optional argument
COPY-CONTENTS. It is not handled yet.
* net/tramp-ftp.el (tramp-disable-ange-ftp): Fix docstring.
(tramp-ftp-file-name-p): Simplify.
* net/tramp-gvfs.el (tramp-gvfs-handle-expand-file-name):
* net/tramp-gw.el (tramp-gw-open-connection): Add hop to
connection vector.
* net/tramp-sh.el (tramp-copy-size-limit): Fix docstring.
(tramp-methods): Do not use `tramp-password-end-of-line'.
(tramp-completion-function-alist-putty): Handle UNIX case.
(tramp-remote-path): Add "/opt/bin", "/opt/sbin" and "/opt/local/bin".
(tramp-do-file-attributes-with-stat)
(tramp-do-directory-files-and-attributes-with-stat) Return uid and
gid as real numbers. They could run out of integer range on cygwin.
(tramp-do-copy-or-rename-file-out-of-band): Better trace format.
(tramp-sh-handle-expand-file-name): Handle hops.
(tramp-open-connection-setup-interactive-shell): Use
`tramp-cleanup'. Move check for busyboxes ...
(tramp-find-shell): ... here. Simplify implementation. Set
"remote-shell" property also for alternative shells.
(tramp-remote-coding-commands): Check "test -c /dev/stdout". If
failing, a regular file would be written otherwise. Reported by
Dmitry Kurochkin <dmitry.kurochkin@gmail.com>.
(tramp-find-inline-encoding): Cache the coding commands in the
process cache. Apply test command on the remote side, if defined.
(tramp-find-inline-compress): Cache the compress commands in the
process cache.
(tramp-compute-multi-hops): Save `tramp-default-proxies-alist'
when requested. Handle hops.
(tramp-current-connection): New defvar.
(tramp-maybe-open-connection): Use `tramp-cleanup'. Throw
`suppress', if there was a failed connection shortly before.
Handle user interrupt. (Bug#10187)
(tramp-get-inline-compress, tramp-get-inline-coding): Read
connection properties from the process cache.
* net/tramp-smb.el (tramp-smb-server-version)
(tramp-smb-wrong-passwd-regexp, tramp-smb-actions-with-tar): New
defconsts.
(tramp-smb-prompt): Extend for powershell prompt.
(tramp-smb-file-name-handler-alist): Add handlers for
`process-file', `shell-command' and `start-file-process'.
(tramp-smb-winexe-program, tramp-smb-winexe-shell-command)
(tramp-smb-winexe-shell-command-switch): New defcustoms.
(tramp-smb-file-name-p): Simplify.
(tramp-smb-action-with-tar, tramp-smb-handle-process-file)
(tramp-smb-kill-winexe-function, tramp-smb-call-winexe)
(tramp-smb-shell-quote-argument): New defuns.
(tramp-smb-handle-copy-directory): Add COPY-CONTENTS argument.
Implement using "tar". By this, time-stamps are preserved.
(tramp-smb-handle-copy-file): Handle also the case of directories.
(tramp-smb-do-file-attributes-with-stat)
(tramp-smb-get-file-entries, tramp-smb-get-cifs-capabilities): Use
`tramp-get-connection-buffer').
(tramp-smb-handle-rename-file): Use "rename", when source and
target are on the same share.
(tramp-smb-maybe-open-connection): Handle wrong passwords. Use
`tramp-smb-server-version'.
(tramp-smb-wait-for-output): Remove prompt.
* net/tramp.el (top): Require 'cl.
(tramp-methods, tramp-rsh-end-of-line): Remove
`tramp-password-end-of-line' from docstring.
(tramp-save-ad-hoc-proxies): New defcustom.
(tramp-completion-function-alist): Adapt docstring.
(tramp-default-password-end-of-line): Remove defcustom.
(tramp-shell-prompt-pattern): Allow "[]" style prompts. (Bug#11065)
(tramp-user-regexp, tramp-file-name-regexp-unified)
(tramp-file-name-regexp-url): Extend regexp by hop separator.
(tramp-postfix-hop-format, tramp-postfix-hop-regexp)
(tramp-remote-file-name-spec-regexp): New defconst.
(tramp-file-name-structure): Extend structure for hops.
(tramp-get-method-parameter): Move up.
(tramp-file-name-p, tramp-dissect-file-name)
(with-parsed-tramp-file-name): Handle hops.
(tramp-file-name-hop): New defun.
(tramp-make-tramp-file-name): New optional arg HOP.
(tramp-message-show-progress-reporter-message): New defvar.
(tramp-with-progress-reporter): Use it. We cannot use
`tramp-message-show-message' here, because this suppresses also
error buffers.
(tramp-error-with-buffer): Suppress buffer view, if
`tramp-message-show-message' is nil. Use
`tramp-get-connection-buffer'.
(tramp-cleanup): New defun.
(tramp-rfn-eshadow-update-overlay): Let-bind `non-essential' to `t'.
(tramp-file-name-handler): If `debug-on-error' is set, propagate
an error unchanged.
(tramp-completion-handle-file-name-all-completions): Handle hops.
Fix an error when called from ido.
(tramp-completion-dissect-file-name): Use better local variable
name. Add hop to the vector.
(tramp-handle-insert-file-contents): Use progress-reporter for the
whole scenario.
(tramp-action-password): Let-bind `enable-recursive-minibuffers'
to `t'.
(tramp-check-for-regexp): Simplify search.
(tramp-enter-password): Remove it. Move implementation ...
(tramp-action-password): ... here.
(tramp-mode-string-to-int, tramp-local-host-p)
(tramp-make-tramp-temp-file, tramp-read-passwd)
(tramp-clear-passwd, tramp-time-less-p, tramp-time-diff): Set
tramp-autoload cookie.
* net/trampver.el: Update release number.
2012-06-11 Thierry Volpiatto <thierry.volpiatto@gmail.com>
Michael Albinus <michael.albinus@gmx.de>
* net/tramp.el (tramp-set-completion-function): Fix docstring.
(tramp-parse-group, tramp-parse-file)
(tramp-parse-shostkeys-sknownhosts): New defuns.
(tramp-parse-rhosts, tramp-parse-rhosts-group, tramp-parse-shosts)
(tramp-parse-shosts-group, tramp-parse-sconfig)
(tramp-parse-sconfig-group, tramp-parse-shostkeys)
(tramp-parse-sknownhosts, tramp-parse-hosts)
(tramp-parse-hosts-group, tramp-parse-passwd, tramp-parse-netrc):
Use them.
(tramp-parse-passwd-group, tramp-parse-netrc-group)
(tramp-parse-putty-group): Don't narrow.
(tramp-parse-putty): Make a loop.
(tramp-file-name-handler): Catch the `suppress' signal.
2012-06-11 Chong Yidong <cyd@gnu.org>
* image.el (imagemagick-register-types): Put the ImageMagick entry
@ -4884,9 +5023,6 @@
* net/tramp.el (tramp-action-login): Set connection property "login-as".
* net/tramp-cache.el (tramp-dump-connection-properties): Do not dump
properties, when "login-as" is set.
* net/tramp-sh.el (tramp-methods): Add user spec to "pscp" and "psftp".
(tramp-default-user-alist): Don't add "pscp".
(tramp-do-copy-or-rename-file-out-of-band): Use connection
@ -6211,9 +6347,6 @@
2011-11-16 Michael Albinus <michael.albinus@gmx.de>
* net/tramp-cache.el (tramp-flush-file-property): Flush also
properties of linked files. (Bug#9879)
* net/tramp-sh.el (tramp-sh-handle-file-truename): Cache only the
local file name.

View file

@ -328,7 +328,8 @@ KEY identifies the connection, it is either a process or a vector."
(not (zerop (hash-table-count tramp-cache-data)))
tramp-cache-data-changed
(stringp tramp-persistency-file-name))
(let ((cache (copy-hash-table tramp-cache-data)))
(let ((cache (copy-hash-table tramp-cache-data))
print-length print-level)
;; Remove temporary data. If there is the key "login-as", we
;; don't save either, because all other properties might
;; depend on the login name, and we want to give the

View file

@ -89,7 +89,9 @@ When called interactively, a Tramp connection has to be selected."
(tramp-flush-directory-property vec "")
;; Flush connection cache.
(tramp-flush-connection-property (tramp-get-connection-process vec))
(when (processp (tramp-get-connection-process vec))
(delete-process (tramp-get-connection-process vec))
(tramp-flush-connection-property (tramp-get-connection-process vec)))
(tramp-flush-connection-property vec)
;; Remove buffers.

View file

@ -194,6 +194,22 @@
"Display MESSAGE temporarily if non-nil while BODY is evaluated."
`(progn ,@body)))
;; `condition-case-unless-debug' is introduced with Emacs 24.
(if (fboundp 'condition-case-unless-debug)
(defalias 'tramp-compat-condition-case-unless-debug
'condition-case-unless-debug)
(defmacro tramp-compat-condition-case-unless-debug
(var bodyform &rest handlers)
"Like `condition-case' except that it does not catch anything when debugging."
(declare (debug condition-case) (indent 2))
(let ((bodysym (make-symbol "body")))
`(let ((,bodysym (lambda () ,bodyform)))
(if debug-on-error
(funcall ,bodysym)
(condition-case ,var
(funcall ,bodysym)
,@handlers))))))
;; `font-lock-add-keywords' does not exist in XEmacs.
(defun tramp-compat-font-lock-add-keywords (mode keywords &optional how)
"Add highlighting KEYWORDS for MODE."
@ -312,43 +328,49 @@ Not actually used. Use `(format \"%o\" i)' instead?"
;; `copy-directory' is a new function in Emacs 23.2. Implementation
;; is taken from there.
(defun tramp-compat-copy-directory
(directory newname &optional keep-time parents)
(directory newname &optional keep-time parents copy-contents)
"Make a copy of DIRECTORY (compat function)."
(if (fboundp 'copy-directory)
(tramp-compat-funcall 'copy-directory directory newname keep-time parents)
(condition-case nil
(tramp-compat-funcall
'copy-directory directory newname keep-time parents copy-contents)
;; If `default-directory' is a remote directory, make sure we find
;; its `copy-directory' handler.
(let ((handler (or (find-file-name-handler directory 'copy-directory)
(find-file-name-handler newname 'copy-directory))))
(if handler
(funcall handler 'copy-directory directory newname keep-time parents)
;; `copy-directory' is either not implemented, or it does not
;; support the the COPY-CONTENTS flag. For the time being, we
;; ignore COPY-CONTENTS as well.
;; Compute target name.
(setq directory (directory-file-name (expand-file-name directory))
newname (directory-file-name (expand-file-name newname)))
(if (and (file-directory-p newname)
(not (string-equal (file-name-nondirectory directory)
(file-name-nondirectory newname))))
(setq newname
(expand-file-name
(file-name-nondirectory directory) newname)))
(if (not (file-directory-p newname)) (make-directory newname parents))
(error
;; If `default-directory' is a remote directory, make sure we
;; find its `copy-directory' handler.
(let ((handler (or (find-file-name-handler directory 'copy-directory)
(find-file-name-handler newname 'copy-directory))))
(if handler
(funcall handler 'copy-directory directory newname keep-time parents)
;; Copy recursively.
(mapc
(lambda (file)
(if (file-directory-p file)
(tramp-compat-copy-directory file newname keep-time parents)
(copy-file file newname t keep-time)))
;; We do not want to delete "." and "..".
(directory-files
directory 'full "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))
;; Compute target name.
(setq directory (directory-file-name (expand-file-name directory))
newname (directory-file-name (expand-file-name newname)))
(if (and (file-directory-p newname)
(not (string-equal (file-name-nondirectory directory)
(file-name-nondirectory newname))))
(setq newname
(expand-file-name
(file-name-nondirectory directory) newname)))
(if (not (file-directory-p newname)) (make-directory newname parents))
;; Set directory attributes.
(set-file-modes newname (file-modes directory))
(if keep-time
(set-file-times newname (nth 5 (file-attributes directory))))))))
;; Copy recursively.
(mapc
(lambda (file)
(if (file-directory-p file)
(tramp-compat-copy-directory file newname keep-time parents)
(copy-file file newname t keep-time)))
;; We do not want to delete "." and "..".
(directory-files
directory 'full "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*"))
;; Set directory attributes.
(set-file-modes newname (file-modes directory))
(if keep-time
(set-file-times newname (nth 5 (file-attributes directory)))))))))
;; TRASH has been introduced with Emacs 24.1.
(defun tramp-compat-delete-file (filename &optional trash)

View file

@ -49,9 +49,8 @@
(defun tramp-disable-ange-ftp ()
"Turn Ange-FTP off.
This is useful for unified remoting. See
`tramp-file-name-structure-unified' and
`tramp-file-name-structure-separate' for details. Requests suitable
for Ange-FTP will be forwarded to Ange-FTP. Also see the variables
`tramp-file-name-structure' for details. Requests suitable for
Ange-FTP will be forwarded to Ange-FTP. Also see the variables
`tramp-ftp-method', `tramp-default-method', and
`tramp-default-method-alist'.
@ -204,8 +203,8 @@ pass to the OPERATION."
;;;###tramp-autoload
(defsubst tramp-ftp-file-name-p (filename)
"Check if it's a filename that should be forwarded to Ange-FTP."
(let ((v (tramp-dissect-file-name filename)))
(string= (tramp-file-name-method v) tramp-ftp-method)))
(string= (tramp-file-name-method (tramp-dissect-file-name filename))
tramp-ftp-method))
;;;###tramp-autoload
(unless (featurep 'xemacs)

View file

@ -625,7 +625,7 @@ is no information where to trace the message.")
;; If there is a default location, expand tilde.
(when (string-match "\\`\\(~\\)\\(/\\|\\'\\)" localname)
(save-match-data
(tramp-gvfs-maybe-open-connection (vector method user host "/")))
(tramp-gvfs-maybe-open-connection (vector method user host "/" hop)))
(setq localname
(replace-match
(tramp-get-file-property v "/" "default-location" "~")

View file

@ -154,7 +154,7 @@ instead of the host name declared in TARGET-VEC."
(memq (process-status tramp-gw-aux-proc) '(listen)))
(let ((aux-vec
(vector "aux" (tramp-file-name-user gw-vec)
(tramp-file-name-host gw-vec) nil)))
(tramp-file-name-host gw-vec) nil nil)))
(setq tramp-gw-aux-proc
(make-network-process
:name (tramp-buffer-name aux-vec) :buffer nil :host 'local

View file

@ -51,8 +51,9 @@ If it is nil, no compression at all will be applied."
:type '(choice (const nil) integer))
(defcustom tramp-copy-size-limit 10240
"The maximum file size where inline copying is preferred over an out-of-the-band copy.
If it is nil, inline out-of-the-band copy will be used without a check."
"The maximum file size where inline copying is preferred over an \
out-of-the-band copy.
If it is nil, out-of-the-band copy will be used without a check."
:group 'tramp
:type '(choice (const nil) integer))
@ -347,7 +348,6 @@ detected as prompt when being sent on echoing hosts, therefore.")
(tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
(tramp-remote-shell "/bin/sh")
(tramp-remote-shell-args ("-c"))
(tramp-password-end-of-line "xy") ;see docstring for "xy"
(tramp-default-port 22)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
@ -356,7 +356,6 @@ detected as prompt when being sent on echoing hosts, therefore.")
(tramp-login-args (("-l" "%u") ("-P" "%p") ("-1" "-ssh") ("%h")))
(tramp-remote-shell "/bin/sh")
(tramp-remote-shell-args ("-c"))
(tramp-password-end-of-line "xy") ;see docstring for "xy"
(tramp-default-port 22)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
@ -384,7 +383,6 @@ detected as prompt when being sent on echoing hosts, therefore.")
("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
(tramp-password-end-of-line "xy") ;see docstring for "xy"
(tramp-default-port 22)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
@ -397,8 +395,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
(tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k")
("-q") ("-r")))
(tramp-copy-keep-date t)
(tramp-copy-recursive t)
(tramp-password-end-of-line "xy"))) ;see docstring for "xy"
(tramp-copy-recursive t)))
;;;###tramp-autoload
(add-to-list 'tramp-methods
'("fcp"
@ -462,9 +459,11 @@ detected as prompt when being sent on echoing hosts, therefore.")
;;;###tramp-autoload
(defconst tramp-completion-function-alist-putty
'((tramp-parse-putty
"HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"))
"Default list of (FUNCTION REGISTRY) pairs to be examined for putty methods.")
`((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.")
;;;###tramp-autoload
(eval-after-load 'tramp
@ -513,9 +512,10 @@ detected as prompt when being sent on echoing hosts, therefore.")
;; IRIX64: /usr/bin
;;;###tramp-autoload
(defcustom tramp-remote-path
'(tramp-default-remote-path "/bin" "/usr/bin" "/usr/sbin" "/usr/local/bin"
"/local/bin" "/local/freeware/bin" "/local/gnu/bin"
"/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin")
'(tramp-default-remote-path "/bin" "/usr/bin" "/usr/sbin"
"/usr/local/bin" "/local/bin" "/local/freeware/bin" "/local/gnu/bin"
"/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin"
"/opt/bin" "/opt/sbin" "/opt/local/bin")
"List of directories to search for executables on remote host.
For every remote host, this variable will be set buffer local,
keeping the list of existing directories on that host.
@ -545,7 +545,6 @@ as given in your `~/.profile'."
,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
"CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=\"\""
"autocorrect=" "correct=")
"List of environment variables to be set on the remote host.
Each element should be a string of the form ENVVARNAME=VALUE. An
@ -1180,9 +1179,6 @@ target of the symlink differ."
(tramp-get-file-exists-command v)
(tramp-shell-quote-argument localname)))))))
;; CCC: This should check for an error condition and signal failure
;; when something goes wrong.
;; Daniel Pittman <daniel@danann.net>
(defun tramp-sh-handle-file-attributes (filename &optional id-format)
"Like `file-attributes' for Tramp files."
(unless id-format (setq id-format 'integer))
@ -1318,8 +1314,8 @@ target of the symlink differ."
(tramp-get-test-command vec)
(tramp-shell-quote-argument localname)
(tramp-get-remote-stat vec)
(if (eq id-format 'integer) "%u" "\"%U\"")
(if (eq id-format 'integer) "%g" "\"%G\"")
(if (eq id-format 'integer) "%ue0" "\"%U\"")
(if (eq id-format 'integer) "%ge0" "\"%G\"")
(tramp-shell-quote-argument localname))))
(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
@ -1702,8 +1698,8 @@ and gid of the corresponding user is taken. Both parameters must be integers."
(tramp-shell-quote-argument localname)
(tramp-get-ls-command vec)
(tramp-get-remote-stat vec)
(if (eq id-format 'integer) "%u" "\"%U\"")
(if (eq id-format 'integer) "%g" "\"%G\""))))
(if (eq id-format 'integer) "%ue0" "\"%U\"")
(if (eq id-format 'integer) "%ge0" "\"%G\""))))
;; This function should return "foo/" for directories and "bar" for
;; files.
@ -2394,7 +2390,7 @@ The method used must be an out-of-band method."
p v nil tramp-actions-copy-out-of-band)))
;; Reset the transfer process properties.
(tramp-message orig-vec 6 "%s" (buffer-string))
(tramp-message orig-vec 6 "\n%s" (buffer-string))
(tramp-set-connection-property v "process-name" nil)
(tramp-set-connection-property v "process-buffer" nil)))
@ -2457,11 +2453,11 @@ The method used must be an out-of-band method."
"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>'
;; 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>)
;; 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))
@ -2699,7 +2695,8 @@ the result will be a local, non-Tramp, filename."
method user host
(tramp-drop-volume-letter
(tramp-run-real-handler
'expand-file-name (list localname))))))))
'expand-file-name (list localname)))
hop)))))
;;; Remote commands:
@ -3609,37 +3606,48 @@ file exists and nonzero exit status otherwise."
(defun tramp-find-shell (vec)
"Opens a shell on the remote host which groks tilde expansion."
(unless (tramp-get-connection-property vec "remote-shell" nil)
(let (shell)
(with-connection-property vec "remote-shell"
(let ((shell (tramp-get-method-parameter
(tramp-file-name-method vec) 'tramp-remote-shell)))
(with-current-buffer (tramp-get-buffer vec)
;; CCC: "root" does not exist always, see QNAP 459. Which
;; check could we apply instead?
(tramp-send-command vec "echo ~root" t)
(cond
((or (string-match "^~root$" (buffer-string))
;; The default shell (ksh93) of OpenSolaris and Solaris
;; is buggy. We've got reports for "SunOS 5.10" and
;; "SunOS 5.11" so far.
(string-match (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
(tramp-get-connection-property vec "uname" "")))
(setq shell
(or (tramp-find-executable
vec "bash" (tramp-get-remote-path vec) t t)
(tramp-find-executable
vec "ksh" (tramp-get-remote-path vec) t t)))
(unless shell
(tramp-error
vec 'file-error
"Couldn't find a shell which groks tilde expansion"))
(tramp-message
vec 5 "Starting remote shell `%s' for tilde expansion"
(tramp-set-connection-property vec "remote-shell" shell))
(tramp-open-shell vec shell))
(when (or (string-match "^~root$" (buffer-string))
;; The default shell (ksh93) of OpenSolaris and
;; Solaris is buggy. We've got reports for "SunOS
;; 5.10" and "SunOS 5.11" so far.
(string-match (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
(tramp-get-connection-property vec "uname" "")))
(if (setq shell
(or (tramp-find-executable
vec "bash" (tramp-get-remote-path vec) t t)
(tramp-find-executable
vec "ksh" (tramp-get-remote-path vec) t t)))
(progn
(tramp-message
vec 5 "Starting remote shell `%s' for tilde expansion" shell)
(tramp-open-shell vec shell))
(t (tramp-message
vec 5 "Remote `%s' groks tilde expansion, good"
(tramp-set-connection-property
vec "remote-shell"
(tramp-get-method-parameter
(tramp-file-name-method vec) 'tramp-remote-shell)))))))))
;; Maybe it works at least for some other commands.
(setq shell
(tramp-get-method-parameter
(tramp-file-name-method vec) 'tramp-remote-shell))
(tramp-message
vec 2
(concat
"Couldn't find a remote shell which groks tilde expansion, "
"using `%s'")
shell)))
;; Busyboxes tend to behave strange. We check for the existence.
(with-connection-property vec "busybox"
(tramp-send-command vec (format "%s --version" shell) t)
(let ((case-fold-search t))
(and (string-match "busybox" (buffer-string)) t)))
;; Return the shell.
shell))))
;; Utility functions.
@ -3747,21 +3755,12 @@ process to set up. VEC specifies the connection."
vec "uname"
(tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
(when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
(with-current-buffer (tramp-get-debug-buffer vec)
;; Keep the debug buffer.
(rename-buffer
(generate-new-buffer-name tramp-temp-buffer-name) 'unique)
(tramp-cleanup-connection vec)
(if (= (point-min) (point-max))
(kill-buffer nil)
(rename-buffer (tramp-debug-buffer-name vec) 'unique))
;; We call `tramp-get-buffer' in order to keep the debug buffer.
(tramp-get-buffer vec)
(tramp-message
vec 3
"Connection reset, because remote host changed from `%s' to `%s'"
old-uname new-uname)
(throw 'uname-changed (tramp-maybe-open-connection vec)))))
(tramp-cleanup vec)
(tramp-message
vec 3
"Connection reset, because remote host changed from `%s' to `%s'"
old-uname new-uname)
(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
@ -3798,17 +3797,6 @@ process to set up. VEC specifies the connection."
;; Disable unexpected output.
(tramp-send-command vec "mesg n; biff n" t)
;; Busyboxes tend to behave strange. We check for the existence.
(with-connection-property vec "busybox"
(tramp-send-command
vec
(format
"%s --version" (tramp-get-connection-property vec "remote-shell" "echo"))
t)
(with-current-buffer (process-buffer proc)
(let ((case-fold-search t))
(and (string-match "busybox" (buffer-string)) 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>.
@ -3902,7 +3890,7 @@ with the encoded or decoded results, respectively.")
(b64 "recode data..base64" "recode base64..data")
(b64 tramp-perl-encode-with-module tramp-perl-decode-with-module)
(b64 tramp-perl-encode tramp-perl-decode)
(uu "uuencode xxx" "uudecode -o /dev/stdout")
(uu "uuencode xxx" "uudecode -o /dev/stdout" "test -c /dev/stdout")
(uu "uuencode xxx" "uudecode -o -")
(uu "uuencode xxx" "uudecode -p")
(uu "uuencode xxx" tramp-uudecode)
@ -3912,7 +3900,7 @@ with the encoded or decoded results, respectively.")
"List of remote coding commands for inline transfer.
Each item is a list that looks like this:
\(FORMAT ENCODING DECODING\)
\(FORMAT ENCODING DECODING [TEST]\)
FORMAT is symbol describing the encoding/decoding format. It can be
`b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
@ -3926,7 +3914,10 @@ input.
If they are variables, this variable is a string containing a Perl
implementation for this functionality. This Perl program will be transferred
to the remote host, and it is available as shell function with the same name.")
to the remote host, and it is available as shell function with the same name.
The optional TEST command can be used for further tests, whether
ENCODING and DECODING are applicable.")
(defun tramp-find-inline-encoding (vec)
"Find an inline transfer encoding that works.
@ -3935,7 +3926,8 @@ Goes through the list `tramp-local-coding-commands' and
(save-excursion
(let ((local-commands tramp-local-coding-commands)
(magic "xyzzy")
loc-enc loc-dec rem-enc rem-dec litem ritem found)
(p (tramp-get-connection-process vec))
loc-enc loc-dec rem-enc rem-dec rem-test litem ritem found)
(while (and local-commands (not found))
(setq litem (pop local-commands))
(catch 'wont-work-local
@ -3968,6 +3960,13 @@ Goes through the list `tramp-local-coding-commands' and
(when (equal format (nth 0 ritem))
(setq rem-enc (nth 1 ritem))
(setq rem-dec (nth 2 ritem))
(setq rem-test (nth 3 ritem))
;; Check the remote test command if exists.
(when (stringp rem-test)
(tramp-message
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 encoding and decoding commands can be
;; called remotely with null input and output. This makes
;; sure there are no syntax errors and the command is really
@ -4019,15 +4018,16 @@ Goes through the list `tramp-local-coding-commands' and
(tramp-error
vec 'file-error "Couldn't find an inline transfer encoding"))
;; Set connection properties.
;; 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-set-connection-property vec "local-encoding" loc-enc)
(tramp-set-connection-property p "local-encoding" loc-enc)
(tramp-message vec 5 "Using local decoding `%s'" loc-dec)
(tramp-set-connection-property vec "local-decoding" loc-dec)
(tramp-set-connection-property p "local-decoding" loc-dec)
(tramp-message vec 5 "Using remote encoding `%s'" rem-enc)
(tramp-set-connection-property vec "remote-encoding" rem-enc)
(tramp-set-connection-property p "remote-encoding" rem-enc)
(tramp-message vec 5 "Using remote decoding `%s'" rem-dec)
(tramp-set-connection-property vec "remote-decoding" rem-dec))))
(tramp-set-connection-property p "remote-decoding" rem-dec))))
(defun tramp-call-local-coding-command (cmd input output)
"Call the local encoding or decoding command.
@ -4065,8 +4065,8 @@ Goes through the list `tramp-inline-compress-commands'."
(save-excursion
(let ((commands tramp-inline-compress-commands)
(magic "xyzzy")
item compress decompress
found)
(p (tramp-get-connection-process vec))
item compress decompress found)
(while (and commands (not found))
(catch 'next
(setq item (pop commands)
@ -4100,16 +4100,18 @@ Goes through the list `tramp-inline-compress-commands'."
;; Did we find something?
(if found
(progn
;; Set connection properties.
;; Set connection properties. Since the commands are
;; risky (due to output direction), we cache them in the
;; process cache.
(tramp-message
vec 5 "Using inline transfer compress command `%s'" compress)
(tramp-set-connection-property vec "inline-compress" compress)
(tramp-set-connection-property p "inline-compress" compress)
(tramp-message
vec 5 "Using inline transfer decompress command `%s'" decompress)
(tramp-set-connection-property vec "inline-decompress" decompress))
(tramp-set-connection-property p "inline-decompress" decompress))
(tramp-set-connection-property vec "inline-compress" nil)
(tramp-set-connection-property vec "inline-decompress" nil)
(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")))))
@ -4117,18 +4119,43 @@ Goes through the list `tramp-inline-compress-commands'."
"Expands VEC according to `tramp-default-proxies-alist'.
Gateway hops are already opened."
(let ((target-alist `(,vec))
(choices tramp-default-proxies-alist)
item proxy)
(hops (or (tramp-file-name-hop vec) ""))
(item vec)
choices proxy)
;; Ad-hoc proxy definitions.
(dolist (proxy (reverse (split-string hops tramp-postfix-hop-regexp 'omit)))
(let ((user (tramp-file-name-user item))
(host (tramp-file-name-host item))
(proxy (concat
tramp-prefix-format proxy tramp-postfix-host-format)))
(tramp-message
vec 5 "Add proxy (\"%s\" \"%s\" \"%s\")"
(and (stringp host) (regexp-quote host))
(and (stringp user) (regexp-quote user))
proxy)
;; Add the hop.
(add-to-list
'tramp-default-proxies-alist
(list (and (stringp host) (regexp-quote host))
(and (stringp user) (regexp-quote user))
proxy))
(setq item (tramp-dissect-file-name proxy))))
;; Save the new value.
(when (and hops tramp-save-ad-hoc-proxies)
(customize-save-variable
'tramp-default-proxies-alist tramp-default-proxies-alist))
;; Look for proxy hosts to be passed.
(setq choices tramp-default-proxies-alist)
(while choices
(setq item (pop choices)
proxy (eval (nth 2 item)))
(when (and
;; host
;; Host.
(string-match (or (eval (nth 0 item)) "")
(or (tramp-file-name-host (car target-alist)) ""))
;; user
;; User.
(string-match (or (eval (nth 1 item)) "")
(or (tramp-file-name-user (car target-alist)) "")))
(if (null proxy)
@ -4164,7 +4191,7 @@ Gateway hops are already opened."
'target-alist
(vector
(tramp-file-name-method hop) (tramp-file-name-user hop)
(tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil))
(tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil nil))
;; For the password prompt, we need the correct values.
;; Therefore, we must remember the gateway vector. But we
;; cannot do it as connection property, because it shouldn't
@ -4212,6 +4239,9 @@ Gateway hops are already opened."
;; Result.
target-alist))
(defvar tramp-current-connection nil
"Last connection timestamp.")
(defun tramp-maybe-open-connection (vec)
"Maybe open a connection VEC.
Does not do anything if a connection is already open, but re-opens the
@ -4222,6 +4252,16 @@ connection if a previous connection has died for some reason."
(process-environment (copy-sequence process-environment))
(pos (with-current-buffer (tramp-get-connection-buffer vec) (point))))
;; If Tramp opens the same connection within a short time frame,
;; there is a problem. We shall signal this.
(unless (or (and p (processp p) (memq (process-status p) '(run open)))
(not (equal (butlast (append vec nil))
(car tramp-current-connection)))
(> (tramp-time-diff
(current-time) (cdr tramp-current-connection))
5))
(throw 'suppress 'suppress))
;; If too much time has passed since last command was sent, look
;; whether process is still alive. If it isn't, kill it. When
;; using ssh, it can sometimes happen that the remote end has
@ -4242,9 +4282,7 @@ connection if a previous connection has died for some reason."
;; The error will be caught locally.
(tramp-error vec 'file-error "Awake did fail")))
(file-error
(tramp-flush-connection-property vec)
(tramp-flush-connection-property p)
(delete-process p)
(tramp-cleanup vec)
(setq p nil)))
;; New connection must be opened.
@ -4293,6 +4331,8 @@ connection if a previous connection has died for some reason."
(tramp-set-connection-property p "vector" vec)
(set-process-sentinel p 'tramp-process-sentinel)
(tramp-compat-set-process-query-on-exit-flag p nil)
(setq tramp-current-connection
(cons (butlast (append vec nil)) (current-time)))
(tramp-message
vec 6 "%s" (mapconcat 'identity (process-command p) " "))
@ -4401,11 +4441,7 @@ connection if a previous connection has died for some reason."
;; When the user did interrupt, we must cleanup.
(quit
(let ((p (tramp-get-connection-process vec)))
(when (and p (processp p))
(tramp-flush-connection-property vec)
(tramp-flush-connection-property p)
(delete-process p)))
(tramp-cleanup vec)
;; Propagate the quit signal.
(signal (car err) (cdr err)))))))
@ -4942,9 +4978,10 @@ the length of the file to be compressed.
If no corresponding command is found, nil is returned."
(when (and (integerp tramp-inline-compress-start-size)
(> size tramp-inline-compress-start-size))
(with-connection-property vec prop
(with-connection-property (tramp-get-connection-process vec) prop
(tramp-find-inline-compress vec)
(tramp-get-connection-property vec prop nil))))
(tramp-get-connection-property
(tramp-get-connection-process vec) prop nil))))
(defun tramp-get-inline-coding (vec prop size)
"Return the coding command related to PROP.
@ -4962,9 +4999,10 @@ function cell is returned to be applied on a buffer."
;; no inline coding is found.
(ignore-errors
(let ((coding
(with-connection-property vec prop
(with-connection-property (tramp-get-connection-process vec) prop
(tramp-find-inline-encoding vec)
(tramp-get-connection-property vec prop nil)))
(tramp-get-connection-property
(tramp-get-connection-process vec) prop nil)))
(prop1 (if (string-match "encoding" prop)
"inline-compress" "inline-decompress"))
compress)

View file

@ -43,7 +43,7 @@
;; We define an empty command, because `tramp-smb-call-winexe'
;; opens already the powershell. Used in `tramp-handle-shell-command'.
(tramp-remote-shell "")
;; This is just a guess. We don't know whether the share "$C"
;; This is just a guess. We don't know whether the share "C$"
;; is available for public use, and whether the user has write
;; access.
(tramp-tmpdir "/C$/Temp"))))
@ -82,8 +82,18 @@ call, letting the SMB client use the default one."
(defvar tramp-smb-version nil
"Version string of the SMB client.")
(defconst tramp-smb-prompt "^smb: .+> \\|^\\s-+Server\\s-+Comment$"
"Regexp used as prompt in smbclient.")
(defconst tramp-smb-server-version
"Domain=\\[[^]]*\\] OS=\\[[^]]*\\] Server=\\[[^]]*\\]"
"Regexp of SMB server identification.")
(defconst tramp-smb-prompt "^\\(smb:\\|PS\\) .+> \\|^\\s-+Server\\s-+Comment$"
"Regexp used as prompt in smbclient or powershell.")
(defconst tramp-smb-wrong-passwd-regexp
(regexp-opt
'("NT_STATUS_LOGON_FAILURE"
"NT_STATUS_WRONG_PASSWORD"))
"Regexp for login error strings of SMB servers.")
(defconst tramp-smb-errors
(mapconcat
@ -155,6 +165,16 @@ This list is used for login to SMB servers.
See `tramp-actions-before-shell' for more info.")
(defconst tramp-smb-actions-with-tar
'((tramp-password-prompt-regexp tramp-action-password)
(tramp-wrong-passwd-regexp tramp-action-permission-denied)
(tramp-smb-errors tramp-action-permission-denied)
(tramp-process-alive-regexp tramp-smb-action-with-tar))
"List of pattern/action pairs.
This list is used for tar-like copy of directories.
See `tramp-actions-before-shell' for more info.")
;; New handlers should be added here.
(defconst tramp-smb-file-name-handler-alist
'(
@ -205,12 +225,14 @@ See `tramp-actions-before-shell' for more info.")
(make-directory . tramp-smb-handle-make-directory)
(make-directory-internal . tramp-smb-handle-make-directory-internal)
(make-symbolic-link . tramp-smb-handle-make-symbolic-link)
(process-file . tramp-smb-handle-process-file)
(rename-file . tramp-smb-handle-rename-file)
(set-file-modes . tramp-smb-handle-set-file-modes)
;; `set-file-selinux-context' performed by default handler.
(set-file-times . ignore)
(set-visited-file-modtime . ignore)
(shell-command . ignore)
(shell-command . tramp-handle-shell-command)
(start-file-process . tramp-smb-handle-start-file-process)
(substitute-in-file-name . tramp-smb-handle-substitute-in-file-name)
(unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
(vc-registered . ignore)
@ -220,11 +242,34 @@ See `tramp-actions-before-shell' for more info.")
"Alist of handler functions for Tramp SMB method.
Operations not mentioned here will be handled by the default Emacs primitives.")
;; Options for remote processes via winexe.
(defcustom tramp-smb-winexe-program "winexe"
"Name of winexe client to run.
If it isn't found in the local $PATH, the absolute path of winexe
shall be given. This is needed for remote processes."
:group 'tramp
:type 'string
:version "24.2")
(defcustom tramp-smb-winexe-shell-command "powershell.exe"
"Shell to be used for processes on remote machines.
This must be Powershell V2 compatible."
:group 'tramp
:type 'string
:version "24.2")
(defcustom tramp-smb-winexe-shell-command-switch "-file -"
"Command switch used together with `tramp-smb-winexe-shell-command'.
This can be used to disable echo etc."
:group 'tramp
:type 'string
:version "24.2")
;;;###tramp-autoload
(defsubst tramp-smb-file-name-p (filename)
"Check if it's a filename for SMB servers."
(let ((v (tramp-dissect-file-name filename)))
(string= (tramp-file-name-method v) tramp-smb-method)))
(string= (tramp-file-name-method (tramp-dissect-file-name filename))
tramp-smb-method))
;;;###tramp-autoload
(defun tramp-smb-file-name-handler (operation &rest args)
@ -287,14 +332,31 @@ pass to the OPERATION."
"error with add-name-to-file, see buffer `%s' for details"
(buffer-name))))))
(defun tramp-smb-action-with-tar (proc vec)
"Untar from connection buffer."
(if (not (memq (process-status proc) '(run open)))
(throw 'tramp-action 'process-died)
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
(when (search-forward-regexp tramp-smb-server-version nil t)
;; There might be a hidden password prompt.
(widen)
(forward-line)
(tramp-message vec 6 (buffer-substring (point-min) (point)))
(delete-region (point-min) (point))
(throw 'tramp-action 'ok)))))
(defun tramp-smb-handle-copy-directory
(dirname newname &optional keep-date parents copy-contents)
"Like `copy-directory' for Tramp files. KEEP-DATE is not handled."
"Like `copy-directory' for Tramp files."
(setq dirname (expand-file-name dirname)
newname (expand-file-name newname))
(let ((t1 (tramp-tramp-file-p dirname))
(t2 (tramp-tramp-file-p newname)))
(with-parsed-tramp-file-name (if t1 dirname newname) nil
(tramp-with-progress-reporter
v 0 (format "Copying %s to %s" dirname newname)
(cond
;; We must use a local temporary directory.
((and t1 t2)
@ -311,46 +373,121 @@ pass to the OPERATION."
;; We can copy recursively.
((or t1 t2)
(let ((prompt (tramp-smb-send-command v "prompt"))
(recurse (tramp-smb-send-command v "recurse")))
(unless (file-directory-p newname)
(when (and (file-directory-p newname)
(not (string-equal (file-name-nondirectory dirname)
(file-name-nondirectory newname))))
(setq newname
(expand-file-name
(file-name-nondirectory dirname) newname))
(if t2 (setq v (tramp-dissect-file-name newname))))
(if (not (file-directory-p newname))
(make-directory newname parents))
(setq tramp-current-method (tramp-file-name-method v)
tramp-current-user (tramp-file-name-user v)
tramp-current-host (tramp-file-name-real-host v))
(let* ((real-user (tramp-file-name-real-user v))
(real-host (tramp-file-name-real-host v))
(domain (tramp-file-name-domain v))
(port (tramp-file-name-port v))
(share (tramp-smb-get-share v))
(localname (file-name-as-directory
(replace-regexp-in-string
"\\\\" "/" (tramp-smb-get-localname v))))
(tmpdir (make-temp-name
(expand-file-name
tramp-temp-name-prefix
(tramp-compat-temporary-file-directory))))
(args (list tramp-smb-program
(concat "//" real-host "/" share) "-E")))
(if (not (zerop (length real-user)))
(setq args (append args (list "-U" real-user)))
(setq args (append args (list "-N"))))
(when domain (setq args (append args (list "-W" domain))))
(when port (setq args (append args (list "-p" port))))
(when tramp-smb-conf
(setq args (append args (list "-s" tramp-smb-conf))))
(setq args
(if t1
;; Source is remote.
(append args
(list "-D" (shell-quote-argument localname)
"-c" (shell-quote-argument "tar qc - *")
"|" "tar" "xfC" "-"
(shell-quote-argument tmpdir)))
;; Target is remote.
(append (list "tar" "cfC" "-" (shell-quote-argument dirname)
"." "|")
args
(list "-D" (shell-quote-argument localname)
"-c" (shell-quote-argument "tar qx -")))))
(unwind-protect
(unless
(and
prompt recurse
(tramp-smb-send-command
v (format "cd \"%s\"" (tramp-smb-get-localname v)))
(tramp-smb-send-command
v (format "lcd \"%s\"" (if t1 newname dirname)))
(if t1
(tramp-smb-send-command v "mget *")
(tramp-smb-send-command v "mput *")))
;; Error.
(with-current-buffer (tramp-get-connection-buffer v)
(goto-char (point-min))
(search-forward-regexp tramp-smb-errors nil t)
(tramp-error
v 'file-error
"%s `%s'" (match-string 0) (if t1 dirname newname))))
;; Go home.
(tramp-smb-send-command
v (format
"cd %s" (if (tramp-smb-get-cifs-capabilities v) "/" "\\")))
;; Toggle prompt and recurse OFF.
(if prompt (tramp-smb-send-command v "prompt"))
(if recurse (tramp-smb-send-command v "recurse")))))
(with-temp-buffer
;; Set the transfer process properties.
(tramp-set-connection-property
v "process-name" (buffer-name (current-buffer)))
(tramp-set-connection-property
v "process-buffer" (current-buffer))
(when t1
;; The smbclient tar command creates always complete
;; paths. We must emulate the directory structure,
;; and symlink to the real target.
(make-directory
(expand-file-name ".." (concat tmpdir localname)) 'parents)
(make-symbolic-link
newname (directory-file-name (concat tmpdir localname))))
;; Use an asynchronous processes. By this, password
;; can be handled.
(let* ((default-directory tmpdir)
(p (start-process-shell-command
(tramp-get-connection-name v)
(tramp-get-connection-buffer v)
(mapconcat 'identity args " "))))
(tramp-message
v 6 "%s" (mapconcat 'identity (process-command p) " "))
(tramp-compat-set-process-query-on-exit-flag p nil)
(tramp-process-actions p v nil tramp-smb-actions-with-tar)
(while (memq (process-status p) '(run open))
(sit-for 0.1))
(tramp-message v 6 "\n%s" (buffer-string))))
;; Reset the transfer process properties.
(tramp-set-connection-property v "process-name" nil)
(tramp-set-connection-property v "process-buffer" nil)
(when t1 (delete-directory tmpdir 'recurse))))
;; Handle KEEP-DATE argument.
(when keep-date
(set-file-times newname (nth 5 (file-attributes dirname))))
;; Set the mode.
(unless keep-date
(set-file-modes newname (tramp-default-file-modes dirname)))
;; When newname did exist, we have wrong cached values.
(when t2
(with-parsed-tramp-file-name newname nil
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname))))
;; We must do it file-wise.
(t
(tramp-run-real-handler
'copy-directory (list dirname newname keep-date parents)))))))
'copy-directory (list dirname newname keep-date parents))))))))
(defun tramp-smb-handle-copy-file
(filename newname &optional ok-if-already-exists keep-date
preserve-uid-gid preserve-selinux-context)
"Like `copy-file' for Tramp files.
KEEP-DATE is not handled in case NEWNAME resides on an SMB server.
KEEP-DATE has no effect in case NEWNAME resides on an SMB server.
PRESERVE-UID-GID and PRESERVE-SELINUX-CONTEXT are completely ignored."
(setq filename (expand-file-name filename)
newname (expand-file-name newname))
@ -358,40 +495,43 @@ PRESERVE-UID-GID and PRESERVE-SELINUX-CONTEXT are completely ignored."
(tramp-dissect-file-name (if (file-remote-p filename) filename newname))
0 (format "Copying %s to %s" filename newname)
(let ((tmpfile (file-local-copy filename)))
(if (file-directory-p filename)
(tramp-compat-copy-directory filename newname keep-date t t)
(if tmpfile
;; Remote filename.
(condition-case err
(rename-file tmpfile newname ok-if-already-exists)
((error quit)
(delete-file tmpfile)
(signal (car err) (cdr err))))
(let ((tmpfile (file-local-copy filename)))
(if tmpfile
;; Remote filename.
(condition-case err
(rename-file tmpfile newname ok-if-already-exists)
((error quit)
(delete-file tmpfile)
(signal (car err) (cdr err))))
;; Remote newname.
(when (file-directory-p newname)
(setq newname
(expand-file-name (file-name-nondirectory filename) newname)))
;; Remote newname.
(when (file-directory-p newname)
(setq newname
(expand-file-name (file-name-nondirectory filename) newname)))
(with-parsed-tramp-file-name newname nil
(when (and (not ok-if-already-exists)
(file-exists-p newname))
(tramp-error v 'file-already-exists newname))
(with-parsed-tramp-file-name newname nil
(when (and (not ok-if-already-exists)
(file-exists-p newname))
(tramp-error v 'file-already-exists newname))
;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there.
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname)
(unless (tramp-smb-get-share v)
(tramp-error
v 'file-error "Target `%s' must contain a share name" newname))
(unless (tramp-smb-send-command
v (format "put \"%s\" \"%s\""
filename (tramp-smb-get-localname v)))
(tramp-error v 'file-error "Cannot copy `%s'" filename))))))
;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there.
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname)
(unless (tramp-smb-get-share v)
(tramp-error
v 'file-error "Target `%s' must contain a share name" newname))
(unless (tramp-smb-send-command
v (format "put \"%s\" \"%s\""
filename (tramp-smb-get-localname v)))
(tramp-error v 'file-error "Cannot copy `%s'" filename))))))
;; KEEP-DATE handling.
(when keep-date (set-file-times newname (nth 5 (file-attributes filename)))))
;; KEEP-DATE handling.
(when keep-date
(set-file-times newname (nth 5 (file-attributes filename))))))
(defun tramp-smb-handle-delete-directory (directory &optional recursive)
"Like `delete-directory' for Tramp files."
@ -539,7 +679,7 @@ PRESERVE-UID-GID and PRESERVE-SELINUX-CONTEXT are completely ignored."
"Implement `file-attributes' for Tramp files using stat command."
(tramp-message
vec 5 "file attributes with stat: %s" (tramp-file-name-localname vec))
(with-current-buffer (tramp-get-buffer vec)
(with-current-buffer (tramp-get-connection-buffer vec)
(let* (size id link uid gid atime mtime ctime mode inode)
(when (tramp-smb-send-command
vec (format "stat \"%s\"" (tramp-smb-get-localname vec)))
@ -845,44 +985,170 @@ target of the symlink differ."
"error with make-symbolic-link, see buffer `%s' for details"
(buffer-name))))))
(defun tramp-smb-handle-process-file
(program &optional infile destination display &rest args)
"Like `process-file' for Tramp files."
;; The implementation is not complete yet.
(when (and (numberp destination) (zerop destination))
(error "Implementation does not handle immediate return"))
(with-parsed-tramp-file-name default-directory nil
(let* ((name (file-name-nondirectory program))
(name1 name)
(i 0)
input tmpinput outbuf command ret)
;; Determine input.
(when infile
(setq infile (expand-file-name infile))
(if (tramp-equal-remote default-directory infile)
;; INFILE is on the same remote host.
(setq input (with-parsed-tramp-file-name infile nil localname))
;; INFILE must be copied to remote host.
(setq input (tramp-make-tramp-temp-file v)
tmpinput (tramp-make-tramp-file-name method user host input))
(copy-file infile tmpinput t))
;; Transform input into a filename powershell does understand.
(setq input (format "//%s%s" host input)))
;; Determine output.
(cond
;; Just a buffer.
((bufferp destination)
(setq outbuf destination))
;; A buffer name.
((stringp destination)
(setq outbuf (get-buffer-create destination)))
;; (REAL-DESTINATION ERROR-DESTINATION)
((consp destination)
;; output.
(cond
((bufferp (car destination))
(setq outbuf (car destination)))
((stringp (car destination))
(setq outbuf (get-buffer-create (car destination))))
((car destination)
(setq outbuf (current-buffer))))
;; stderr.
(tramp-message v 2 "%s" "STDERR not supported"))
;; 't
(destination
(setq outbuf (current-buffer))))
;; Construct command.
(setq command (mapconcat 'identity (cons program args) " ")
command (if input
(format
"get-content %s | & %s"
(tramp-smb-shell-quote-argument input) command)
(format "& %s" command)))
(while (get-process name1)
;; NAME must be unique as process name.
(setq i (1+ i)
name1 (format "%s<%d>" name i)))
;; Set the new process properties.
(tramp-set-connection-property v "process-name" name1)
(tramp-set-connection-property
v "process-buffer"
(or outbuf (generate-new-buffer tramp-temp-buffer-name)))
;; Call it.
(condition-case nil
(with-current-buffer (tramp-get-connection-buffer v)
;; Preserve buffer contents.
(narrow-to-region (point-max) (point-max))
(tramp-smb-call-winexe v)
(when (tramp-smb-get-share v)
(tramp-smb-send-command
v (format "cd \"//%s%s\"" host (file-name-directory localname))))
(tramp-smb-send-command v command)
;; Preserve command output.
(narrow-to-region (point-max) (point-max))
(let ((p (tramp-get-connection-process v)))
(tramp-smb-send-command v "exit $lasterrorcode")
(while (memq (process-status p) '(run open))
(sleep-for 0.1)
(setq ret (process-exit-status p))))
(delete-region (point-min) (point-max))
(widen))
;; When the user did interrupt, we should do it also. We use
;; return code -1 as marker.
(quit
(setq ret -1))
;; Handle errors.
(error
(setq ret 1)))
;; We should show the output anyway.
(when (and outbuf display) (display-buffer outbuf))
;; Cleanup. We remove all file cache values for the connection,
;; because the remote process could have changed them.
(tramp-set-connection-property v "process-name" nil)
(tramp-set-connection-property v "process-buffer" nil)
(when tmpinput (delete-file tmpinput))
(unless outbuf
(kill-buffer (tramp-get-connection-property v "process-buffer" nil)))
;; `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)))
(tramp-flush-directory-property v ""))
;; Return exit status.
(if (equal ret -1)
(keyboard-quit)
ret))))
(defun tramp-smb-handle-rename-file
(filename newname &optional ok-if-already-exists)
"Like `rename-file' for Tramp files."
(setq filename (expand-file-name filename)
newname (expand-file-name newname))
(when (and (not ok-if-already-exists)
(file-exists-p newname))
(tramp-error
(tramp-dissect-file-name
(if (file-remote-p filename) filename newname))
'file-already-exists newname))
(tramp-with-progress-reporter
(tramp-dissect-file-name (if (file-remote-p filename) filename newname))
0 (format "Renaming %s to %s" filename newname)
(let ((tmpfile (file-local-copy filename)))
(if (and (tramp-equal-remote filename newname)
(string-equal
(tramp-smb-get-share (tramp-dissect-file-name filename))
(tramp-smb-get-share (tramp-dissect-file-name newname))))
;; We can rename directly.
(with-parsed-tramp-file-name filename v1
(with-parsed-tramp-file-name newname v2
(if tmpfile
;; Remote filename.
(condition-case err
(rename-file tmpfile newname ok-if-already-exists)
((error quit)
(delete-file tmpfile)
(signal (car err) (cdr err))))
;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there.
(tramp-flush-file-property v2 (file-name-directory v2-localname))
(tramp-flush-file-property v2 v2-localname)
(unless (tramp-smb-get-share v2)
(tramp-error
v2 'file-error "Target `%s' must contain a share name" newname))
(unless (tramp-smb-send-command
v2 (format "rename \"%s\" \"%s\""
(tramp-smb-get-localname v1)
(tramp-smb-get-localname v2)))
(tramp-error v2 'file-error "Cannot rename `%s'" filename))))
;; Remote newname.
(when (file-directory-p newname)
(setq newname (expand-file-name
(file-name-nondirectory filename) newname)))
(with-parsed-tramp-file-name newname nil
(when (and (not ok-if-already-exists)
(file-exists-p newname))
(tramp-error v 'file-already-exists newname))
;; We must also flush the cache of the directory, because
;; `file-attributes' reads the values from there.
(tramp-flush-file-property v (file-name-directory localname))
(tramp-flush-file-property v localname)
(unless (tramp-smb-send-command
v (format "put %s \"%s\""
filename (tramp-smb-get-localname v)))
(tramp-error v 'file-error "Cannot rename `%s'" filename)))))
(delete-file filename)))
;; We must rename via copy.
(tramp-compat-copy-file filename newname ok-if-already-exists t t t)
(if (file-directory-p filename)
(tramp-compat-delete-directory filename 'recursive)
(delete-file filename)))))
(defun tramp-smb-handle-set-file-modes (filename mode)
"Like `set-file-modes' for Tramp files."
@ -896,6 +1162,54 @@ target of the symlink differ."
(tramp-error
v 'file-error "Error while changing file's mode %s" filename)))))
;; We use BUFFER also as connection buffer during setup. Because of
;; this, its original contents must be saved, and restored once
;; connection has been setup.
(defun tramp-smb-handle-start-file-process (name buffer program &rest args)
"Like `start-file-process' for Tramp files."
(with-parsed-tramp-file-name default-directory nil
(let ((command (mapconcat 'identity (cons program args) " "))
(bmp (and (buffer-live-p buffer) (buffer-modified-p buffer)))
(name1 name)
(i 0))
(unwind-protect
(save-excursion
(save-restriction
(unless buffer
;; BUFFER can be nil. We use a temporary buffer.
(setq buffer (generate-new-buffer tramp-temp-buffer-name)))
(while (get-process name1)
;; NAME must be unique as process name.
(setq i (1+ i)
name1 (format "%s<%d>" name i)))
;; Set the new process properties.
(tramp-set-connection-property v "process-name" name1)
(tramp-set-connection-property v "process-buffer" buffer)
;; Activate narrowing in order to save BUFFER contents.
(with-current-buffer (tramp-get-connection-buffer v)
(let ((buffer-undo-list t))
(narrow-to-region (point-max) (point-max))
(tramp-smb-call-winexe v)
(when (tramp-smb-get-share v)
(tramp-smb-send-command
v (format
"cd \"//%s%s\""
host (file-name-directory localname))))
(tramp-message v 6 "(%s); exit" command)
(tramp-send-string v command)))
;; Return value.
(tramp-get-connection-process v)))
;; Save exit.
(with-current-buffer (tramp-get-connection-buffer v)
(if (string-match tramp-temp-buffer-name (buffer-name))
(progn
(set-process-buffer (tramp-get-connection-process v) nil)
(kill-buffer (current-buffer)))
(set-buffer-modified-p bmp)))
(tramp-set-connection-property v "process-name" nil)
(tramp-set-connection-property v "process-buffer" nil)))))
(defun tramp-smb-handle-substitute-in-file-name (filename)
"Like `handle-substitute-in-file-name' for Tramp files.
\"//\" substitutes only in the local filename part. Catches
@ -999,7 +1313,7 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
(with-parsed-tramp-file-name (file-name-as-directory directory) nil
(setq localname (or localname "/"))
(with-file-property v localname "file-entries"
(with-current-buffer (tramp-get-buffer v)
(with-current-buffer (tramp-get-connection-buffer v)
(let* ((share (tramp-smb-get-share v))
(cache (tramp-get-connection-property v "share-cache" nil))
res entry)
@ -1187,7 +1501,7 @@ Result is the list (LOCALNAME MODE SIZE MTIME)."
(tramp-get-connection-process vec) "cifs-capabilities"
(save-match-data
(when (tramp-smb-send-command vec "posix")
(with-current-buffer (tramp-get-buffer vec)
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
(when
(re-search-forward "Server supports CIFS capabilities" nil t)
@ -1216,18 +1530,20 @@ Returns nil if there has been an error message from smbclient."
(tramp-send-string vec command)
(tramp-smb-wait-for-output vec))
(defun tramp-smb-maybe-open-connection (vec)
(defun tramp-smb-maybe-open-connection (vec &optional argument)
"Maybe open a connection to HOST, log in as USER, using `tramp-smb-program'.
Does not do anything if a connection is already open, but re-opens the
connection if a previous connection has died for some reason."
connection if a previous connection has died for some reason.
If ARGUMENT is non-nil, use it as argument for
`tramp-smb-winexe-program', and suppress any checks."
(let* ((share (tramp-smb-get-share vec))
(buf (tramp-get-buffer vec))
(buf (tramp-get-connection-buffer vec))
(p (get-buffer-process buf)))
;; Check whether we still have the same smbclient version.
;; Otherwise, we must delete the connection cache, because
;; capabilities migh have changed.
(unless (processp p)
(unless (or argument (processp p))
(let ((default-directory (tramp-compat-temporary-file-directory))
(command (concat tramp-smb-program " -V")))
@ -1271,9 +1587,10 @@ connection if a previous connection has died for some reason."
;; Check whether it is still the same share.
(unless
(and p (processp p) (memq (process-status p) '(run open))
(string-equal
share
(tramp-get-connection-property p "smb-share" "")))
(or argument
(string-equal
share
(tramp-get-connection-property p "smb-share" ""))))
(save-match-data
;; There might be unread output from checking for share names.
@ -1288,9 +1605,13 @@ connection if a previous connection has died for some reason."
(port (tramp-file-name-port vec))
args)
(if share
(setq args (list (concat "//" real-host "/" share)))
(setq args (list "-g" "-L" real-host )))
(cond
(argument
(setq args (list (concat "//" real-host))))
(share
(setq args (list (concat "//" real-host "/" share))))
(t
(setq args (list "-g" "-L" real-host ))))
(if (not (zerop (length real-user)))
(setq args (append args (list "-U" real-user)))
@ -1300,6 +1621,8 @@ connection if a previous connection has died for some reason."
(when port (setq args (append args (list "-p" port))))
(when tramp-smb-conf
(setq args (append args (list "-s" tramp-smb-conf))))
(when argument
(setq args (append args (list argument))))
;; OK, let's go.
(tramp-with-progress-reporter
@ -1313,8 +1636,11 @@ connection if a previous connection has died for some reason."
(p (let ((default-directory
(tramp-compat-temporary-file-directory)))
(apply #'start-process
(tramp-buffer-name vec) (tramp-get-buffer vec)
tramp-smb-program args))))
(tramp-get-connection-name vec)
(tramp-get-connection-buffer vec)
(if argument
tramp-smb-winexe-program tramp-smb-program)
args))))
(tramp-message
vec 6 "%s" (mapconcat 'identity (process-command p) " "))
@ -1325,40 +1651,58 @@ connection if a previous connection has died for some reason."
tramp-current-user user
tramp-current-host host)
;; Play login scenario.
(tramp-process-actions
p vec nil
(if share
tramp-smb-actions-with-share
tramp-smb-actions-without-share))
(condition-case err
(let (tramp-message-show-message)
;; Play login scenario.
(tramp-process-actions
p vec nil
(if (or argument share)
tramp-smb-actions-with-share
tramp-smb-actions-without-share))
;; Check server version.
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
(search-forward-regexp
"Domain=\\[[^]]*\\] OS=\\[[^]]*\\] Server=\\[[^]]*\\]" nil t)
(let ((smbserver-version (match-string 0)))
(unless
(string-equal
smbserver-version
(tramp-get-connection-property
vec "smbserver-version" smbserver-version))
(tramp-flush-directory-property vec "")
(tramp-flush-connection-property vec))
(tramp-set-connection-property
vec "smbserver-version" smbserver-version)))
;; Check server version.
(unless argument
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
(search-forward-regexp tramp-smb-server-version nil t)
(let ((smbserver-version (match-string 0)))
(unless
(string-equal
smbserver-version
(tramp-get-connection-property
vec "smbserver-version" smbserver-version))
(tramp-flush-directory-property vec "")
(tramp-flush-connection-property vec))
(tramp-set-connection-property
vec "smbserver-version" smbserver-version))))
;; Set chunksize. Otherwise, `tramp-send-string' might
;; try it itself.
(tramp-set-connection-property p "smb-share" share)
(tramp-set-connection-property
p "chunksize" tramp-chunksize))))))))
;; Set chunksize. Otherwise, `tramp-send-string' might
;; try it itself.
(tramp-set-connection-property p "smb-share" share)
(tramp-set-connection-property
p "chunksize" tramp-chunksize))
;; Check for the error reason. If it was due to wrong
;; password, reestablish the connection. We cannot
;; handle this in `tramp-process-actions', because
;; smbclient does not ask for the password, again.
(error
(with-current-buffer (tramp-get-connection-buffer vec)
(goto-char (point-min))
(if (search-forward-regexp
tramp-smb-wrong-passwd-regexp nil t)
;; Disable `auth-source' and `password-cache'.
(let (auth-sources)
(tramp-cleanup vec)
(tramp-smb-maybe-open-connection vec argument))
;; Propagate the error.
(signal (car err) (cdr err)))))))))))))
;; We don't use timeouts. If needed, the caller shall wrap around.
(defun tramp-smb-wait-for-output (vec)
"Wait for output from smbclient command.
Returns nil if an error message has appeared."
(with-current-buffer (tramp-get-buffer vec)
(with-current-buffer (tramp-get-connection-buffer vec)
(let ((p (get-buffer-process (current-buffer)))
(found (progn (goto-char (point-min))
(re-search-forward tramp-smb-prompt nil t)))
@ -1392,10 +1736,68 @@ Returns nil if an error message has appeared."
(goto-char (point-min))
(setq found (re-search-forward tramp-smb-prompt nil t)))
;; Return value is whether no error message has appeared.
(tramp-message vec 6 "\n%s" (buffer-string))
;; Remove prompt.
(when found
(goto-char (point-max))
(re-search-backward tramp-smb-prompt nil t)
(delete-region (point) (point-max)))
;; Return value is whether no error message has appeared.
(not err))))
(defun tramp-smb-kill-winexe-function ()
"Send SIGKILL to the winexe process."
(ignore-errors
(let ((p (get-buffer-process (current-buffer))))
(when (and p (processp p) (memq (process-status p) '(run open)))
(signal-process (process-id p) 'SIGINT)))))
(defun tramp-smb-call-winexe (vec)
"Apply a remote command, if possible, using `tramp-smb-winexe-program'."
;; We call `tramp-get-buffer' in order to get a debug buffer for
;; messages.
(tramp-get-buffer vec)
;; Check for program.
(unless (let ((default-directory
(tramp-compat-temporary-file-directory)))
(executable-find tramp-smb-winexe-program))
(tramp-error
vec 'file-error "Cannot find program: %s" tramp-smb-winexe-program))
;; winexe does not supports ports.
(when (tramp-file-name-port vec)
(tramp-error vec 'file-error "Port not supported for remote processes"))
(tramp-smb-maybe-open-connection
vec
(format
"%s %s"
tramp-smb-winexe-shell-command tramp-smb-winexe-shell-command-switch))
(set (make-local-variable 'kill-buffer-hook)
'(tramp-smb-kill-winexe-function))
;; Suppress "^M". Shouldn't we specify utf8?
(set-process-coding-system (tramp-get-connection-process vec) 'raw-text-dos)
;; Set width to 128. This avoids mixing prompt and long error messages.
(tramp-smb-send-command vec "$rawui = (Get-Host).UI.RawUI")
(tramp-smb-send-command vec "$bufsize = $rawui.BufferSize")
(tramp-smb-send-command vec "$winsize = $rawui.WindowSize")
(tramp-smb-send-command vec "$bufsize.Width = 128")
(tramp-smb-send-command vec "$winsize.Width = 128")
(tramp-smb-send-command vec "$rawui.BufferSize = $bufsize")
(tramp-smb-send-command vec "$rawui.WindowSize = $winsize"))
(defun tramp-smb-shell-quote-argument (s)
"Similar to `shell-quote-argument', but uses windows cmd syntax."
(let ((system-type 'ms-dos))
(shell-quote-argument s)))
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-smb 'force)))
@ -1404,12 +1806,9 @@ Returns nil if an error message has appeared."
;;; TODO:
;; * Error handling in case password is wrong.
;; * Return more comprehensive file permission string.
;; * Try to remove the inclusion of dummy "" directory. Seems to be at
;; several places, especially in `tramp-smb-handle-insert-directory'.
;; * (RMS) Use unwind-protect to clean up the state so as to make the state
;; regular again.
;; * Ignore case in file names.
;;; tramp-smb.el ends here

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,7 @@
;; should be changed only there.
;;;###tramp-autoload
(defconst tramp-version "2.2.3-24.1"
(defconst tramp-version "2.2.6-pre"
"This version of Tramp.")
;;;###tramp-autoload
@ -44,7 +44,7 @@
(= emacs-major-version 21)
(>= emacs-minor-version 4)))
"ok"
(format "Tramp 2.2.3-24.1 is not fit for %s"
(format "Tramp 2.2.6-pre is not fit for %s"
(when (string-match "^.*$" (emacs-version))
(match-string 0 (emacs-version)))))))
(unless (string-match "\\`ok\\'" x) (error "%s" x)))