aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorKai Großjohann2004-02-29 17:52:17 +0000
committerKai Großjohann2004-02-29 17:52:17 +0000
commit5ec2cc41db095268a8597af7705bfc3d156b99db (patch)
tree0dcf5f2e73da2e610f04417e80290c58f314e814 /lisp
parentcc86f83f38c5c9ffbe8ac6a2a5ba35b9e9080a93 (diff)
downloademacs-5ec2cc41db095268a8597af7705bfc3d156b99db.tar.gz
emacs-5ec2cc41db095268a8597af7705bfc3d156b99db.zip
Tramp: sync with upstream version 2.0.39.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog99
-rw-r--r--lisp/net/tramp-ftp.el17
-rw-r--r--lisp/net/tramp-smb.el137
-rw-r--r--lisp/net/tramp.el766
-rw-r--r--lisp/net/trampver.el2
5 files changed, 704 insertions, 317 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 6bb5012c332..d112071c5be 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,102 @@
12004-02-29 Kai Grossjohann <kai.grossjohann@gmx.net>
2 Version 2.0.39 of Tramp released.
3
4 * net/tramp.el (tramp-handle-file-local-copy)
5 (tramp-handle-write-region, tramp-open-connection-rsh): Variable
6 name typo. Small change. From Patrick Tullmann
7 <tullmann@flux.utah.edu>.
8 (tramp-process-connection-type): New variable.
9 (tramp-maybe-open-connection): Use it.
10 (tramp-do-copy-or-rename-via-buffer): Handle KEEP-DATE arg, if
11 possible.
12 (tramp-touch): Set last-modified time of a remote file.
13 (tramp-handle-write-region): Say which function is used when
14 encoding.
15
16
172004-02-29 Michael Albinus <Michael.Albinus@alcatel.de>
18
19 * net/tramp-smb.el (tramp-smb-handle-file-writable-p): Handle the
20 case of non-existing filename, too. Reported by Christoph Bauer
21 <c_bauer@informatik.uni-kl.de>.
22 (tramp-smb-get-file-entries): The directory in question should
23 have permissions "drwxrwxrwx". Just virtual, because we don't
24 know the real permissions. Don't we know?
25 (tramp-smb-prompt): Add virtual prompt from listing shares, too.
26 (tramp-smb-errors): Add "NT_STATUS_ACCOUNT_LOCKED_OUT".
27 (tramp-smb-wait-for-output): Optimize algorithm getting pending
28 output. If it was received chunkwise, there have been problems.
29 Remove the "prompt not found" error message; it is obvious.
30 Simplify algorithm.
31 (tramp-smb-process-running): Removed. Since we acknowledge the
32 virtual prompt for shares, there's no need for distinction of
33 reading shares (process ends afterwards) and interactive mode of
34 smblient.
35 (tramp-smb-open-connection): Setting process sentinel removed.
36 (tramp-smb-errors): Add "NT_STATUS_WRONG_PASSWORD" and
37 "NT_STATUS_NETWORK_ACCESS_DENIED".
38 (tramp-smb-maybe-open-connection): Set `process-connection-type'
39 to 'pty. Suggested by Piet van Oostrum <piet@cs.uu.nl>.
40 (top-level): Setting default value in `tramp-default-method-alist'
41 corrected. Order of USER and HOST have been wrong. Nobody
42 claimed for months ...
43 (tramp-smb-maybe-open-connection): Use
44 `tramp-process-connection-type'.
45 (tramp-smb-open-connection): Clear password cache if login has
46 failed.
47
48 * net/tramp.el (tramp-completion-mode) Don't check for 'xemacs but
49 `tramp-unified-filenames'.
50 (tramp-completion-mode): Make test for XEmacs explicitely.
51 `event-to-character' can exists in Emacs packages too. Reported
52 by Matt Swift <swift@alum.mit.edu>.
53 (tramp-buffer-name): Buffer name must contain the user if exists.
54 Reported by Adrian Phillips <a.phillips@met.no>.
55 (tramp-do-copy-or-rename-file): Handle out-of-band methods. Call
56 `tramp-do-copy-or-rename-file-out-of-band' this case.
57 (tramp-do-copy-or-rename-file-out-of-band): Renamed from
58 `tramp-do-copy-or-rename-file-one-local', because it handles also
59 the case both files use the same out-of-band method.
60 Implementation added.
61 (tramp-handle-file-local-copy, tramp-handle-write-region):
62 Out-of-band handling removed. `copy-file' called instead, which
63 calls `tramp-do-copy-or-rename-file-out-of-band'.
64 (tramp-action-password): Check for out-of-band method removed.
65 This function is used for 'login-program.
66 (tramp-post-connection): Use `tramp-method-out-of-band-p' when
67 appropriate.
68 (tramp-completion-function-alist-ssh): Add `tramp-parse-shostkeys'
69 and `tramp-parse-sknownhosts'.
70 (tramp-completion-function-alist): It's a defvar now, because we
71 want to apply the optimized `tramp-set-completion-function'
72 instead of a static list.
73 (tramp-set-completion-function): Implementation tuned. Avoid
74 double entries, and entries where the function or the
75 file/directory doesn't exist.
76 (tramp-parse-shostkeys, tramp-parse-sknownhosts): New functions
77 for SSH2.
78 (tramp-file-name-handler-alist): Add `dired-compress-file' entry.
79 (tramp-handle-dired-compress-file): New function.
80 (tramp-async-proc): New variable.
81 (tramp-handle-shell-command): Adding asynchronous processes. They
82 are far from being perfect, but it works at least for
83 `find-grep-dired' and `find-name-dired' in Emacs 21.4.
84 (top-level): Require password.el if visible. Should be mandatory
85 once No Gnus has found its way into (X)Emacs.
86 (tramp-read-passwd): Invoke `password-read' if available,
87 `read-passwd' otherwise. `ange-ftp-read-passwd' isn't used as
88 fallback any longer.
89 (tramp-clear-passwd): New function.
90 (tramp-process-actions, tramp-process-multi-actions): Clear
91 password cache if login has failed.
92
93 * net/tramp-ftp.el (Commentary): Remove pointer to EFS. It has
94 its own module.
95 (tramp-ftp-file-name-handler): Unset `ange-ftp-ftp-name-arg' and
96 `ange-ftp-ftp-name-res'. There could be incorrect values from
97 previous calls in case the "ftp" method is used in the Tramp file
98 name. Reported by Katsumi Yamaoka <yamaoka@jpl.org>.
99
12004-02-28 Richard M. Stallman <rms@gnu.org> 1002004-02-28 Richard M. Stallman <rms@gnu.org>
2 101
3 * term.el (term-mouse-paste): Call mouse-set-point. 102 * term.el (term-mouse-paste): Call mouse-set-point.
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el
index c81e49bf77c..3be891a49f8 100644
--- a/lisp/net/tramp-ftp.el
+++ b/lisp/net/tramp-ftp.el
@@ -1,6 +1,6 @@
1;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP and EFS -*- coding: iso-8859-1; -*- 1;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP and EFS -*- coding: iso-8859-1; -*-
2 2
3;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Michael Albinus <Michael.Albinus@alcatel.de> 5;; Author: Michael Albinus <Michael.Albinus@alcatel.de>
6;; Keywords: comm, processes 6;; Keywords: comm, processes
@@ -24,8 +24,8 @@
24 24
25;;; Commentary: 25;;; Commentary:
26 26
27;; Convenience functions for calling Ange-FTP (and maybe EFS, later on) 27;; Convenience functions for calling Ange-FTP from Tramp.
28;; from Tramp. Most of them are displaced from tramp.el. 28;; Most of them are displaced from tramp.el.
29 29
30;;; Code: 30;;; Code:
31 31
@@ -98,9 +98,16 @@ pass to the OPERATION."
98 (list (nth 0 tramp-file-name-structure) 98 (list (nth 0 tramp-file-name-structure)
99 (nth 3 tramp-file-name-structure) 99 (nth 3 tramp-file-name-structure)
100 (nth 2 tramp-file-name-structure) 100 (nth 2 tramp-file-name-structure)
101 (nth 4 tramp-file-name-structure)))) 101 (nth 4 tramp-file-name-structure)))
102 ;; ange-ftp uses `ange-ftp-ftp-name-arg' and `ange-ftp-ftp-name-res'
103 ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active,
104 ;; there could be incorrect values from previous calls in case the
105 ;; "ftp" method is used in the Tramp file name. So we unset
106 ;; those values.
107 (ange-ftp-ftp-name-arg "")
108 (ange-ftp-ftp-name-res nil))
102 (cond 109 (cond
103 ;; If argument is a symlink, 'file-directory-p` and 'file-exists-p` 110 ;; If argument is a symlink, `file-directory-p' and `file-exists-p'
104 ;; call the traversed file recursively. So we cannot disable the 111 ;; call the traversed file recursively. So we cannot disable the
105 ;; file-name-handler this case. 112 ;; file-name-handler this case.
106 ((memq operation '(file-directory-p file-exists-p)) 113 ((memq operation '(file-directory-p file-exists-p))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 95f3fb330c4..ab6ad3310c1 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -1,6 +1,6 @@
1;;; tramp-smb.el --- Tramp access functions for SMB servers -*- coding: iso-8859-1; -*- 1;;; tramp-smb.el --- Tramp access functions for SMB servers -*- coding: iso-8859-1; -*-
2 2
3;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 4
5;; Author: Michael Albinus <Michael.Albinus@alcatel.de> 5;; Author: Michael Albinus <Michael.Albinus@alcatel.de>
6;; Keywords: comm, processes 6;; Keywords: comm, processes
@@ -50,7 +50,7 @@
50;; Add a default for `tramp-default-method-alist'. Rule: If there is 50;; Add a default for `tramp-default-method-alist'. Rule: If there is
51;; a domain in USER, it must be the SMB method. 51;; a domain in USER, it must be the SMB method.
52(add-to-list 'tramp-default-method-alist 52(add-to-list 'tramp-default-method-alist
53 (list "%" "" tramp-smb-method)) 53 (list "" "%" tramp-smb-method))
54 54
55;; Add completion function for SMB method. 55;; Add completion function for SMB method.
56(tramp-set-completion-function 56(tramp-set-completion-function
@@ -62,7 +62,7 @@
62 :group 'tramp 62 :group 'tramp
63 :type 'string) 63 :type 'string)
64 64
65(defconst tramp-smb-prompt "^smb: \\S-+> " 65(defconst tramp-smb-prompt "^smb: \\S-+> \\|^\\s-+Server\\s-+Comment$"
66 "Regexp used as prompt in smbclient.") 66 "Regexp used as prompt in smbclient.")
67 67
68(defconst tramp-smb-errors 68(defconst tramp-smb-errors
@@ -71,8 +71,8 @@
71 '(; Connection error 71 '(; Connection error
72 "Connection to \\S-+ failed" 72 "Connection to \\S-+ failed"
73 ; Samba 73 ; Samba
74 "ERRSRV"
75 "ERRDOS" 74 "ERRDOS"
75 "ERRSRV"
76 "ERRbadfile" 76 "ERRbadfile"
77 "ERRbadpw" 77 "ERRbadpw"
78 "ERRfilexists" 78 "ERRfilexists"
@@ -81,13 +81,16 @@
81 "ERRnosuchshare" 81 "ERRnosuchshare"
82 ; Windows NT 4.0, Windows 5.0 (Windows 2000), Windows 5.1 (Windows XP) 82 ; Windows NT 4.0, Windows 5.0 (Windows 2000), Windows 5.1 (Windows XP)
83 "NT_STATUS_ACCESS_DENIED" 83 "NT_STATUS_ACCESS_DENIED"
84 "NT_STATUS_ACCOUNT_LOCKED_OUT"
84 "NT_STATUS_BAD_NETWORK_NAME" 85 "NT_STATUS_BAD_NETWORK_NAME"
85 "NT_STATUS_CANNOT_DELETE" 86 "NT_STATUS_CANNOT_DELETE"
86 "NT_STATUS_LOGON_FAILURE" 87 "NT_STATUS_LOGON_FAILURE"
88 "NT_STATUS_NETWORK_ACCESS_DENIED"
87 "NT_STATUS_NO_SUCH_FILE" 89 "NT_STATUS_NO_SUCH_FILE"
88 "NT_STATUS_OBJECT_NAME_INVALID" 90 "NT_STATUS_OBJECT_NAME_INVALID"
89 "NT_STATUS_OBJECT_NAME_NOT_FOUND" 91 "NT_STATUS_OBJECT_NAME_NOT_FOUND"
90 "NT_STATUS_SHARING_VIOLATION") 92 "NT_STATUS_SHARING_VIOLATION"
93 "NT_STATUS_WRONG_PASSWORD")
91 "\\|") 94 "\\|")
92 "Regexp for possible error strings of SMB servers. 95 "Regexp for possible error strings of SMB servers.
93Used instead of analyzing error codes of commands.") 96Used instead of analyzing error codes of commands.")
@@ -102,12 +105,6 @@ This variable is local to each buffer.")
102This variable is local to each buffer.") 105This variable is local to each buffer.")
103(make-variable-buffer-local 'tramp-smb-share-cache) 106(make-variable-buffer-local 'tramp-smb-share-cache)
104 107
105(defvar tramp-smb-process-running nil
106 "Flag whether a corresponding process is still running.
107Will be changed by corresponding `process-sentinel'.
108This variable is local to each buffer.")
109(make-variable-buffer-local 'tramp-smb-process-running)
110
111(defvar tramp-smb-inodes nil 108(defvar tramp-smb-inodes nil
112 "Keeps virtual inodes numbers for SMB files.") 109 "Keeps virtual inodes numbers for SMB files.")
113 110
@@ -452,19 +449,23 @@ KEEP-DATE is not handled in case NEWNAME resides on an SMB server."
452 449
453(defun tramp-smb-handle-file-writable-p (filename) 450(defun tramp-smb-handle-file-writable-p (filename)
454 "Like `file-writable-p' for tramp files." 451 "Like `file-writable-p' for tramp files."
455; (with-parsed-tramp-file-name filename nil 452 (if (not (file-exists-p filename))
456 (let (user host localname) 453 (let ((dir (file-name-directory filename)))
457 (with-parsed-tramp-file-name filename l 454 (and (file-exists-p dir)
458 (setq user l-user host l-host localname l-localname)) 455 (file-writable-p dir)))
459 (save-excursion 456; (with-parsed-tramp-file-name filename nil
460 (let* ((share (tramp-smb-get-share localname)) 457 (let (user host localname)
461 (file (tramp-smb-get-localname localname nil)) 458 (with-parsed-tramp-file-name filename l
462 (entries (tramp-smb-get-file-entries user host share file)) 459 (setq user l-user host l-host localname l-localname))
463 (entry (and entries 460 (save-excursion
464 (assoc (file-name-nondirectory file) entries)))) 461 (let* ((share (tramp-smb-get-share localname))
465 (and entry 462 (file (tramp-smb-get-localname localname nil))
466 (string-match "w" (nth 1 entry)) 463 (entries (tramp-smb-get-file-entries user host share file))
467 t))))) 464 (entry (and entries
465 (assoc (file-name-nondirectory file) entries))))
466 (and share entry
467 (string-match "w" (nth 1 entry))
468 t))))))
468 469
469(defun tramp-smb-handle-insert-directory 470(defun tramp-smb-handle-insert-directory
470 (filename switches &optional wildcard full-directory-p) 471 (filename switches &optional wildcard full-directory-p)
@@ -733,9 +734,12 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
733 ;; Cache share entries 734 ;; Cache share entries
734 (setq tramp-smb-share-cache res))) 735 (setq tramp-smb-share-cache res)))
735 736
736
737 ;; Add directory itself 737 ;; Add directory itself
738 (add-to-list 'res '("" "dr-xr-xr-x" 0 (0 0))) 738 (add-to-list 'res '("" "drwxrwxrwx" 0 (0 0)))
739
740 ;; There's a very strange error (debugged with XEmacs 21.4.14)
741 ;; If there's no short delay, it returns nil. No idea about
742 (when (featurep 'xemacs) (sleep-for 0.01))
739 743
740 ;; Check for matching entries 744 ;; Check for matching entries
741 (delq nil (mapcar 745 (delq nil (mapcar
@@ -913,7 +917,8 @@ there has been an error message from smbclient."
913 "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'. 917 "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'.
914Does not do anything if a connection is already open, but re-opens the 918Does not do anything if a connection is already open, but re-opens the
915connection if a previous connection has died for some reason." 919connection if a previous connection has died for some reason."
916 (let ((p (get-buffer-process 920 (let ((process-connection-type tramp-process-connection-type)
921 (p (get-buffer-process
917 (tramp-get-buffer nil tramp-smb-method user host)))) 922 (tramp-get-buffer nil tramp-smb-method user host))))
918 (save-excursion 923 (save-excursion
919 (set-buffer (tramp-get-buffer nil tramp-smb-method user host)) 924 (set-buffer (tramp-get-buffer nil tramp-smb-method user host))
@@ -987,11 +992,7 @@ Domain names in USER and port numbers in HOST are acknowledged."
987 (tramp-message 9 "Started process %s" (process-command p)) 992 (tramp-message 9 "Started process %s" (process-command p))
988 (process-kill-without-query p) 993 (process-kill-without-query p)
989 (set-buffer buffer) 994 (set-buffer buffer)
990 (set-process-sentinel 995 (setq tramp-smb-share share)
991 p (lambda (proc str) (setq tramp-smb-process-running nil)))
992 ; If no share is given, the process will terminate
993 (setq tramp-smb-process-running share
994 tramp-smb-share share)
995 996
996 ; send password 997 ; send password
997 (when real-user 998 (when real-user
@@ -1000,54 +1001,44 @@ Domain names in USER and port numbers in HOST are acknowledged."
1000 (tramp-enter-password p pw-prompt))) 1001 (tramp-enter-password p pw-prompt)))
1001 1002
1002 (unless (tramp-smb-wait-for-output user host) 1003 (unless (tramp-smb-wait-for-output user host)
1004 (tramp-clear-passwd user host)
1003 (error "Cannot open connection //%s@%s/%s" 1005 (error "Cannot open connection //%s@%s/%s"
1004 user host (or share ""))))))) 1006 user host (or share "")))))))
1005 1007
1006;; We don't use timeouts. If needed, the caller shall wrap around. 1008;; We don't use timeouts. If needed, the caller shall wrap around.
1007(defun tramp-smb-wait-for-output (user host) 1009(defun tramp-smb-wait-for-output (user host)
1008 "Wait for output from smbclient command. 1010 "Wait for output from smbclient command.
1009Sets position to begin of buffer.
1010Returns nil if an error message has appeared." 1011Returns nil if an error message has appeared."
1011 (save-excursion 1012 (let ((proc (get-buffer-process (current-buffer)))
1012 (let ((proc (get-buffer-process (current-buffer))) 1013 (found (progn (goto-char (point-min))
1013 (found (progn (goto-char (point-max)) 1014 (re-search-forward tramp-smb-prompt nil t)))
1014 (beginning-of-line) 1015 (err (progn (goto-char (point-min))
1015 (looking-at tramp-smb-prompt))) 1016 (re-search-forward tramp-smb-errors nil t))))
1016 err) 1017
1017 (save-match-data 1018 ;; Algorithm: get waiting output. See if last line contains
1018 ;; Algorithm: get waiting output. See if last line contains 1019 ;; tramp-smb-prompt sentinel or tramp-smb-errors strings.
1019 ;; tramp-smb-prompt sentinel, or process has exited. 1020 ;; If not, wait a bit and again get waiting output.
1020 ;; If not, wait a bit and again get waiting output. 1021 (while (and (not found) (not err))
1021 (while (and (not found) tramp-smb-process-running) 1022
1022 (accept-process-output proc) 1023 ;; Accept pending output.
1023 (goto-char (point-max)) 1024 (accept-process-output proc)
1024 (beginning-of-line) 1025
1025 (setq found (looking-at tramp-smb-prompt))) 1026 ;; Search for prompt.
1026
1027 ;; There might be pending output. If tramp-smb-prompt sentinel
1028 ;; hasn't been found, the process has died already. We should
1029 ;; give it a chance.
1030 (when (not found) (accept-process-output nil 1))
1031
1032 ;; Search for errors.
1033 (goto-char (point-min))
1034 (setq err (re-search-forward tramp-smb-errors nil t)))
1035
1036 ;; Add output to debug buffer if appropriate.
1037 (when tramp-debug-buffer
1038 (append-to-buffer
1039 (tramp-get-debug-buffer nil tramp-smb-method user host)
1040 (point-min) (point-max))
1041 (when (and (not found) tramp-smb-process-running)
1042 (save-excursion
1043 (set-buffer
1044 (tramp-get-debug-buffer nil tramp-smb-method user host))
1045 (goto-char (point-max))
1046 (insert (format "[[Remote prompt `%s' not found]]\n"
1047 tramp-smb-prompt)))))
1048 (goto-char (point-min)) 1027 (goto-char (point-min))
1049 ;; Return value is whether no error message has appeared. 1028 (setq found (re-search-forward tramp-smb-prompt nil t))
1050 (not err)))) 1029
1030 ;; Search for errors.
1031 (goto-char (point-min))
1032 (setq err (re-search-forward tramp-smb-errors nil t)))
1033
1034 ;; Add output to debug buffer if appropriate.
1035 (when tramp-debug-buffer
1036 (append-to-buffer
1037 (tramp-get-debug-buffer nil tramp-smb-method user host)
1038 (point-min) (point-max)))
1039
1040 ;; Return value is whether no error message has appeared.
1041 (not err)))
1051 1042
1052 1043
1053;; Snarfed code from time-date.el and parse-time.el 1044;; Snarfed code from time-date.el and parse-time.el
@@ -1125,8 +1116,6 @@ Return the difference in the format of a time value."
1125;; * Provide a local smb.conf. The default one might not be readable. 1116;; * Provide a local smb.conf. The default one might not be readable.
1126;; * Error handling in case password is wrong. 1117;; * Error handling in case password is wrong.
1127;; * Read password from "~/.netrc". 1118;; * Read password from "~/.netrc".
1128;; * Use different buffers for different shares. By this, the password
1129;; won't be requested again when changing shares on the same host.
1130;; * Return more comprehensive file permission string. Think whether it is 1119;; * Return more comprehensive file permission string. Think whether it is
1131;; possible to implement `set-file-modes'. 1120;; possible to implement `set-file-modes'.
1132;; * Handle WILDCARD and FULL-DIRECTORY-P in 1121;; * Handle WILDCARD and FULL-DIRECTORY-P in
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 949d76364fc..cd6ed337927 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1,7 +1,7 @@
1;;; -*- mode: Emacs-Lisp; coding: iso-2022-7bit; -*- 1;;; -*- mode: Emacs-Lisp; coding: iso-2022-7bit; -*-
2;;; tramp.el --- Transparent Remote Access, Multiple Protocol 2;;; tramp.el --- Transparent Remote Access, Multiple Protocol
3 3
4;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 4;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 5
6;; Author: kai.grossjohann@gmx.net 6;; Author: kai.grossjohann@gmx.net
7;; Keywords: comm, processes 7;; Keywords: comm, processes
@@ -72,6 +72,12 @@
72 72
73(require 'timer) 73(require 'timer)
74(require 'format-spec) ;from Gnus 5.8, also in tar ball 74(require 'format-spec) ;from Gnus 5.8, also in tar ball
75;; As long as password.el is not part of (X)Emacs, it shouldn't
76;; be mandatory
77(if (featurep 'xemacs)
78 (load "password" 'noerror)
79 (require 'password nil 'noerror)) ;from No Gnus, also in tar ball
80
75;; The explicit check is not necessary in Emacs, which provides the 81;; The explicit check is not necessary in Emacs, which provides the
76;; feature even if implemented in C, but it appears to be necessary 82;; feature even if implemented in C, but it appears to be necessary
77;; in XEmacs. 83;; in XEmacs.
@@ -628,14 +634,18 @@ See `tramp-methods' for a list of possibilities for METHOD."
628;; Default values for non-Unices seeked 634;; Default values for non-Unices seeked
629(defconst tramp-completion-function-alist-ssh 635(defconst tramp-completion-function-alist-ssh
630 (unless (memq system-type '(windows-nt)) 636 (unless (memq system-type '(windows-nt))
631 '((tramp-parse-rhosts "/etc/hosts.equiv") 637 '((tramp-parse-rhosts "/etc/hosts.equiv")
632 (tramp-parse-rhosts "/etc/shosts.equiv") 638 (tramp-parse-rhosts "/etc/shosts.equiv")
633 (tramp-parse-shosts "/etc/ssh_known_hosts") 639 (tramp-parse-shosts "/etc/ssh_known_hosts")
634 (tramp-parse-sconfig "/etc/ssh_config") 640 (tramp-parse-sconfig "/etc/ssh_config")
635 (tramp-parse-rhosts "~/.rhosts") 641 (tramp-parse-shostkeys "/etc/ssh2/hostkeys")
636 (tramp-parse-rhosts "~/.shosts") 642 (tramp-parse-sknownhosts "/etc/ssh2/knownhosts")
637 (tramp-parse-shosts "~/.ssh/known_hosts") 643 (tramp-parse-rhosts "~/.rhosts")
638 (tramp-parse-sconfig "~/.ssh/config"))) 644 (tramp-parse-rhosts "~/.shosts")
645 (tramp-parse-shosts "~/.ssh/known_hosts")
646 (tramp-parse-sconfig "~/.ssh/config")
647 (tramp-parse-shostkeys "~/.ssh2/hostkeys")
648 (tramp-parse-sknownhosts "~/.ssh2/knownhosts")))
639 "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.") 649 "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")
640 650
641;; Default values for non-Unices seeked 651;; Default values for non-Unices seeked
@@ -650,53 +660,79 @@ See `tramp-methods' for a list of possibilities for METHOD."
650 '((tramp-parse-passwd "/etc/passwd"))) 660 '((tramp-parse-passwd "/etc/passwd")))
651 "Default list of (FUNCTION FILE) pairs to be examined for su methods.") 661 "Default list of (FUNCTION FILE) pairs to be examined for su methods.")
652 662
653(defcustom tramp-completion-function-alist 663(defvar tramp-completion-function-alist nil
654 (list (cons "rcp" tramp-completion-function-alist-rsh)
655 (cons "scp" tramp-completion-function-alist-ssh)
656 (cons "scp1" tramp-completion-function-alist-ssh)
657 (cons "scp2" tramp-completion-function-alist-ssh)
658 (cons "scp1_old" tramp-completion-function-alist-ssh)
659 (cons "scp2_old" tramp-completion-function-alist-ssh)
660 (cons "rsync" tramp-completion-function-alist-rsh)
661 (cons "remcp" tramp-completion-function-alist-rsh)
662 (cons "rsh" tramp-completion-function-alist-rsh)
663 (cons "ssh" tramp-completion-function-alist-ssh)
664 (cons "ssh1" tramp-completion-function-alist-ssh)
665 (cons "ssh2" tramp-completion-function-alist-ssh)
666 (cons "ssh1_old" tramp-completion-function-alist-ssh)
667 (cons "ssh2_old" tramp-completion-function-alist-ssh)
668 (cons "remsh" tramp-completion-function-alist-rsh)
669 (cons "telnet" tramp-completion-function-alist-telnet)
670 (cons "su" tramp-completion-function-alist-su)
671 (cons "sudo" tramp-completion-function-alist-su)
672 (cons "multi" nil)
673 (cons "scpx" tramp-completion-function-alist-ssh)
674 (cons "sshx" tramp-completion-function-alist-ssh)
675 (cons "krlogin" tramp-completion-function-alist-rsh)
676 (cons "plink" tramp-completion-function-alist-ssh)
677 (cons "plink1" tramp-completion-function-alist-ssh)
678 (cons "pscp" tramp-completion-function-alist-ssh)
679 (cons "fcp" tramp-completion-function-alist-ssh)
680 )
681 "*Alist of methods for remote files. 664 "*Alist of methods for remote files.
682This is a list of entries of the form (NAME PAIR1 PAIR2 ...). 665This is a list of entries of the form (NAME PAIR1 PAIR2 ...).
683Each NAME stands for a remote access method. Each PAIR is of the form 666Each NAME stands for a remote access method. Each PAIR is of the form
684\(FUNCTION FILE). FUNCTION is responsible to extract user names and host 667\(FUNCTION FILE). FUNCTION is responsible to extract user names and host
685names from FILE for completion. The following predefined FUNCTIONs exists: 668names from FILE for completion. The following predefined FUNCTIONs exists:
686 669
687 * `tramp-parse-rhosts' for \"~/.rhosts\" like files, 670 * `tramp-parse-rhosts' for \"~/.rhosts\" like files,
688 * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files, 671 * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files,
689 * `tramp-parse-sconfig' for \"~/.ssh/config\" like files, 672 * `tramp-parse-sconfig' for \"~/.ssh/config\" like files,
690 * `tramp-parse-hosts' for \"/etc/hosts\" like files, and 673 * `tramp-parse-shostkeys' for \"~/.ssh2/hostkeys/*\" like files,
691 * `tramp-parse-passwd' for \"/etc/passwd\" like files. 674 * `tramp-parse-sknownhosts' for \"~/.ssh2/knownhosts/*\" like files,
692 * `tramp-parse-netrc' for \"~/.netrc\" like files. 675 * `tramp-parse-hosts' for \"/etc/hosts\" like files,
693 676 * `tramp-parse-passwd' for \"/etc/passwd\" like files.
694FUNCTION can also see a customer defined function. For more details see 677 * `tramp-parse-netrc' for \"~/.netrc\" like files.
695the info pages." 678
696 :group 'tramp 679FUNCTION can also be a customer defined function. For more details see
697 :type '(repeat 680the info pages.")
698 (cons string 681
699 (choice (const nil) (repeat (list function file)))))) 682(eval-after-load "tramp"
683 '(progn
684 (tramp-set-completion-function
685 "rcp" tramp-completion-function-alist-rsh)
686 (tramp-set-completion-function
687 "scp" tramp-completion-function-alist-ssh)
688 (tramp-set-completion-function
689 "scp1" tramp-completion-function-alist-ssh)
690 (tramp-set-completion-function
691 "scp2" tramp-completion-function-alist-ssh)
692 (tramp-set-completion-function
693 "scp1_old" tramp-completion-function-alist-ssh)
694 (tramp-set-completion-function
695 "scp2_old" tramp-completion-function-alist-ssh)
696 (tramp-set-completion-function
697 "rsync" tramp-completion-function-alist-rsh)
698 (tramp-set-completion-function
699 "remcp" tramp-completion-function-alist-rsh)
700 (tramp-set-completion-function
701 "rsh" tramp-completion-function-alist-rsh)
702 (tramp-set-completion-function
703 "ssh" tramp-completion-function-alist-ssh)
704 (tramp-set-completion-function
705 "ssh1" tramp-completion-function-alist-ssh)
706 (tramp-set-completion-function
707 "ssh2" tramp-completion-function-alist-ssh)
708 (tramp-set-completion-function
709 "ssh1_old" tramp-completion-function-alist-ssh)
710 (tramp-set-completion-function
711 "ssh2_old" tramp-completion-function-alist-ssh)
712 (tramp-set-completion-function
713 "remsh" tramp-completion-function-alist-rsh)
714 (tramp-set-completion-function
715 "telnet" tramp-completion-function-alist-telnet)
716 (tramp-set-completion-function
717 "su" tramp-completion-function-alist-su)
718 (tramp-set-completion-function
719 "sudo" tramp-completion-function-alist-su)
720 (tramp-set-completion-function
721 "multi" nil)
722 (tramp-set-completion-function
723 "scpx" tramp-completion-function-alist-ssh)
724 (tramp-set-completion-function
725 "sshx" tramp-completion-function-alist-ssh)
726 (tramp-set-completion-function
727 "krlogin" tramp-completion-function-alist-rsh)
728 (tramp-set-completion-function
729 "plink" tramp-completion-function-alist-ssh)
730 (tramp-set-completion-function
731 "plink1" tramp-completion-function-alist-ssh)
732 (tramp-set-completion-function
733 "pscp" tramp-completion-function-alist-ssh)
734 (tramp-set-completion-function
735 "fcp" tramp-completion-function-alist-ssh)))
700 736
701(defcustom tramp-rsh-end-of-line "\n" 737(defcustom tramp-rsh-end-of-line "\n"
702 "*String used for end of line in rsh connections. 738 "*String used for end of line in rsh connections.
@@ -1267,6 +1303,17 @@ this variable to be set as well."
1267 :group 'tramp 1303 :group 'tramp
1268 :type '(choice (const nil) integer)) 1304 :type '(choice (const nil) integer))
1269 1305
1306;; Logging in to a remote host normally requires obtaining a pty. But
1307;; Emacs on MacOS X has process-connection-type set to nil by default,
1308;; so on those systems Tramp doesn't obtain a pty. Here, we allow
1309;; for an override of the system default.
1310(defcustom tramp-process-connection-type t
1311 "Overrides `process-connection-type' for connections from Tramp.
1312Tramp binds process-connection-type to the value given here before
1313opening a connection to a remote host."
1314 :group 'tramp
1315 :type '(choice (const nil) (const t) (const pty)))
1316
1270;;; Internal Variables: 1317;;; Internal Variables:
1271 1318
1272(defvar tramp-buffer-file-attributes nil 1319(defvar tramp-buffer-file-attributes nil
@@ -1638,6 +1685,7 @@ on the FILENAME argument, even if VISIT was a string.")
1638 (insert-file-contents . tramp-handle-insert-file-contents) 1685 (insert-file-contents . tramp-handle-insert-file-contents)
1639 (write-region . tramp-handle-write-region) 1686 (write-region . tramp-handle-write-region)
1640 (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) 1687 (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
1688 (dired-compress-file . tramp-handle-dired-compress-file)
1641 (dired-call-process . tramp-handle-dired-call-process) 1689 (dired-call-process . tramp-handle-dired-call-process)
1642 (dired-recursive-delete-directory 1690 (dired-recursive-delete-directory
1643 . tramp-handle-dired-recursive-delete-directory) 1691 . tramp-handle-dired-recursive-delete-directory)
@@ -1761,15 +1809,30 @@ Example:
1761 '((tramp-parse-sconfig \"/etc/ssh_config\") 1809 '((tramp-parse-sconfig \"/etc/ssh_config\")
1762 (tramp-parse-sconfig \"~/.ssh/config\")))" 1810 (tramp-parse-sconfig \"~/.ssh/config\")))"
1763 1811
1764 (let ((v (cdr (assoc method tramp-completion-function-alist)))) 1812 (let ((r function-list)
1765 (if v (setcdr v function-list) 1813 (v function-list))
1814 (setq tramp-completion-function-alist
1815 (delete (assoc method tramp-completion-function-alist)
1816 tramp-completion-function-alist))
1817
1818 (while v
1819 ;; Remove double entries
1820 (when (member (car v) (cdr v))
1821 (setcdr v (delete (car v) (cdr v))))
1822 ;; Check for function and file
1823 (unless (and (functionp (nth 0 (car v)))
1824 (file-exists-p (nth 1 (car v))))
1825 (setq r (delete (car v) r)))
1826 (setq v (cdr v)))
1827
1828 (when r
1766 (add-to-list 'tramp-completion-function-alist 1829 (add-to-list 'tramp-completion-function-alist
1767 (cons method function-list))))) 1830 (cons method r)))))
1768 1831
1769(defun tramp-get-completion-function (method) 1832(defun tramp-get-completion-function (method)
1770 "Returns list of completion functions for METHOD. 1833 "Returns list of completion functions for METHOD.
1771For definition of that list see `tramp-set-completion-function'." 1834For definition of that list see `tramp-set-completion-function'."
1772 (cdr (assoc method tramp-completion-function-alist))) 1835 (cdr (assoc method tramp-completion-function-alist)))
1773 1836
1774;;; File Name Handler Functions: 1837;;; File Name Handler Functions:
1775 1838
@@ -2586,44 +2649,86 @@ and `rename'. FILENAME and NEWNAME must be absolute file names."
2586 (signal 'file-already-exists 2649 (signal 'file-already-exists
2587 (list newname)))) 2650 (list newname))))
2588 (let ((t1 (tramp-tramp-file-p filename)) 2651 (let ((t1 (tramp-tramp-file-p filename))
2589 (t2 (tramp-tramp-file-p newname))) 2652 (t2 (tramp-tramp-file-p newname))
2653 v1-multi-method v1-method v1-user v1-host v1-localname
2654 v2-multi-method v2-method v2-user v2-host v2-localname)
2655
2590 ;; Check which ones of source and target are Tramp files. 2656 ;; Check which ones of source and target are Tramp files.
2657 ;; We cannot invoke `with-parsed-tramp-file-name';
2658 ;; it fails if the file isn't a Tramp file name.
2659 (if t1
2660 (with-parsed-tramp-file-name filename l
2661 (setq v1-multi-method l-multi-method
2662 v1-method l-method
2663 v1-user l-user
2664 v1-host l-host
2665 v1-localname l-localname))
2666 (setq v1-localname filename))
2667 (if t2
2668 (with-parsed-tramp-file-name newname l
2669 (setq v2-multi-method l-multi-method
2670 v2-method l-method
2671 v2-user l-user
2672 v2-host l-host
2673 v2-localname l-localname))
2674 (setq v2-localname newname))
2675
2591 (cond 2676 (cond
2677 ;; Both are Tramp files.
2592 ((and t1 t2) 2678 ((and t1 t2)
2593 ;; Both are Tramp files. 2679 (cond
2594 (with-parsed-tramp-file-name filename v1 2680 ;; Shortcut: if method, host, user are the same for both
2595 (with-parsed-tramp-file-name newname v2 2681 ;; files, we invoke `cp' or `mv' on the remote host
2596 ;; Check if we can use a shortcut. 2682 ;; directly.
2597 (if (and (equal v1-multi-method v2-multi-method) 2683 ((and (equal v1-multi-method v2-multi-method)
2598 (equal v1-method v2-method) 2684 (equal v1-method v2-method)
2599 (equal v1-host v2-host) 2685 (equal v1-user v2-user)
2600 (equal v1-user v2-user)) 2686 (equal v1-host v2-host))
2601 ;; Shortcut: if method, host, user are the same for both 2687 (tramp-do-copy-or-rename-file-directly
2602 ;; files, we invoke `cp' or `mv' on the remote host 2688 op v1-multi-method v1-method v1-user v1-host
2603 ;; directly. 2689 v1-localname v2-localname keep-date))
2604 (tramp-do-copy-or-rename-file-directly 2690 ;; If both source and target are Tramp files,
2605 op v1-multi-method v1-method v1-user v1-host 2691 ;; both are using the same copy-program, then we
2606 v1-localname v2-localname keep-date) 2692 ;; can invoke rcp directly. Note that
2607 ;; The shortcut was not possible. So we copy the 2693 ;; default-directory should point to a local
2608 ;; file first. If the operation was `rename', we go 2694 ;; directory if we want to invoke rcp.
2609 ;; back and delete the original file (if the copy was 2695 ((and (not v1-multi-method)
2610 ;; successful). The approach is simple-minded: we 2696 (not v2-multi-method)
2611 ;; create a new buffer, insert the contents of the 2697 (equal v1-method v2-method)
2612 ;; source file into it, then write out the buffer to 2698 (tramp-method-out-of-band-p
2613 ;; the target file. The advantage is that it doesn't 2699 v1-multi-method v1-method v1-user v1-host)
2614 ;; matter which filename handlers are used for the 2700 (not (string-match "\\([^#]*\\)#\\(.*\\)" v1-host))
2615 ;; source and target file. 2701 (not (string-match "\\([^#]*\\)#\\(.*\\)" v2-host)))
2616 2702 (tramp-do-copy-or-rename-file-out-of-band
2617 ;; CCC: If both source and target are Tramp files, 2703 op filename newname keep-date))
2618 ;; and both are using the same copy-program, then we 2704 ;; No shortcut was possible. So we copy the
2619 ;; can invoke rcp directly. Note that 2705 ;; file first. If the operation was `rename', we go
2620 ;; default-directory should point to a local 2706 ;; back and delete the original file (if the copy was
2621 ;; directory if we want to invoke rcp. 2707 ;; successful). The approach is simple-minded: we
2622 (tramp-do-copy-or-rename-via-buffer 2708 ;; create a new buffer, insert the contents of the
2623 op filename newname keep-date))))) 2709 ;; source file into it, then write out the buffer to
2710 ;; the target file. The advantage is that it doesn't
2711 ;; matter which filename handlers are used for the
2712 ;; source and target file.
2713 (t
2714 (tramp-do-copy-or-rename-via-buffer
2715 op filename newname keep-date))))
2716
2717 ;; One file is a Tramp file, the other one is local.
2624 ((or t1 t2) 2718 ((or t1 t2)
2625 ;; Use the generic method via a Tramp buffer. 2719 ;; If the Tramp file has an out-of-band method, the corresponding
2626 (tramp-do-copy-or-rename-via-buffer op filename newname keep-date)) 2720 ;; copy-program can be invoked.
2721 (if (and (not v1-multi-method)
2722 (not v2-multi-method)
2723 (or (tramp-method-out-of-band-p
2724 v1-multi-method v1-method v1-user v1-host)
2725 (tramp-method-out-of-band-p
2726 v2-multi-method v2-method v2-user v2-host)))
2727 (tramp-do-copy-or-rename-file-out-of-band
2728 op filename newname keep-date)
2729 ;; Use the generic method via a Tramp buffer.
2730 (tramp-do-copy-or-rename-via-buffer op filename newname keep-date)))
2731
2627 (t 2732 (t
2628 ;; One of them must be a Tramp file. 2733 ;; One of them must be a Tramp file.
2629 (error "Tramp implementation says this cannot happen"))))) 2734 (error "Tramp implementation says this cannot happen")))))
@@ -2634,8 +2739,9 @@ and `rename'. FILENAME and NEWNAME must be absolute file names."
2634First arg OP is either `copy' or `rename' and indicates the operation. 2739First arg OP is either `copy' or `rename' and indicates the operation.
2635FILENAME is the source file, NEWNAME the target file. 2740FILENAME is the source file, NEWNAME the target file.
2636KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." 2741KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
2637 (let ((trampbuf (get-buffer-create "*tramp output*"))) 2742 (let ((trampbuf (get-buffer-create "*tramp output*"))
2638 (when keep-date 2743 (modtime (nth 5 (file-attributes filename))))
2744 (when (and keep-date (or (null modtime) (equal modtime '(0 0))))
2639 (tramp-message 2745 (tramp-message
2640 1 (concat "Warning: cannot preserve file time stamp" 2746 1 (concat "Warning: cannot preserve file time stamp"
2641 " with inline copying across machines"))) 2747 " with inline copying across machines")))
@@ -2646,7 +2752,12 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
2646 ;; `jka-compr-inhibit' to t. 2752 ;; `jka-compr-inhibit' to t.
2647 (let ((coding-system-for-write 'binary) 2753 (let ((coding-system-for-write 'binary)
2648 (jka-compr-inhibit t)) 2754 (jka-compr-inhibit t))
2649 (write-region (point-min) (point-max) newname))) 2755 (write-region (point-min) (point-max) newname))
2756 ;; KEEP-DATE handling.
2757 (when (and keep-date
2758 (not (null modtime))
2759 (not (equal modtime '(0 0))))
2760 (tramp-touch newname modtime)))
2650 ;; If the operation was `rename', delete the original file. 2761 ;; If the operation was `rename', delete the original file.
2651 (unless (eq op 'copy) 2762 (unless (eq op 'copy)
2652 (delete-file filename)))) 2763 (delete-file filename))))
@@ -2676,13 +2787,112 @@ If KEEP-DATE is non-nil, preserve the time stamp when copying."
2676 "Copying directly failed, see buffer `%s' for details." 2787 "Copying directly failed, see buffer `%s' for details."
2677 (buffer-name))))) 2788 (buffer-name)))))
2678 2789
2679(defun tramp-do-copy-or-rename-file-one-local 2790(defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date)
2680 (op filename newname keep-date)
2681 "Invoke rcp program to copy. 2791 "Invoke rcp program to copy.
2682One of FILENAME and NEWNAME must be a Tramp name, the other must 2792One of FILENAME and NEWNAME must be a Tramp name, the other must
2683be a local filename. The method used must be an out-of-band method." 2793be a local filename. The method used must be an out-of-band method."
2684 ;; CCC 2794 (let ((trampbuf (get-buffer-create "*tramp output*"))
2685 ) 2795 (t1 (tramp-tramp-file-p filename))
2796 (t2 (tramp-tramp-file-p newname))
2797 v1-multi-method v1-method v1-user v1-host v1-localname
2798 v2-multi-method v2-method v2-user v2-host v2-localname
2799 method copy-program copy-args source target)
2800
2801 ;; Check which ones of source and target are Tramp files.
2802 ;; We cannot invoke `with-parsed-tramp-file-name';
2803 ;; it fails if the file isn't a Tramp file name.
2804 (if t1
2805 (with-parsed-tramp-file-name filename l
2806 (setq v1-multi-method l-multi-method
2807 v1-method l-method
2808 v1-user l-user
2809 v1-host l-host
2810 v1-localname l-localname
2811 method (tramp-find-method
2812 v1-multi-method v1-method v1-user v1-host)
2813 copy-program (tramp-get-method-parameter
2814 v1-multi-method method
2815 v1-user v1-host 'tramp-copy-program)
2816 copy-args (tramp-get-method-parameter
2817 v1-multi-method method
2818 v1-user v1-host 'tramp-copy-args)))
2819 (setq v1-localname filename))
2820
2821 (if t2
2822 (with-parsed-tramp-file-name newname l
2823 (setq v2-multi-method l-multi-method
2824 v2-method l-method
2825 v2-user l-user
2826 v2-host l-host
2827 v2-localname l-localname
2828 method (tramp-find-method
2829 v2-multi-method v2-method v2-user v2-host)
2830 copy-program (tramp-get-method-parameter
2831 v2-multi-method method
2832 v2-user v2-host 'tramp-copy-program)
2833 copy-args (tramp-get-method-parameter
2834 v2-multi-method method
2835 v2-user v2-host 'tramp-copy-args)))
2836 (setq v2-localname newname))
2837
2838 ;; The following should be changed. We need a more general
2839 ;; mechanism to parse extra host args.
2840 (if (not t1)
2841 (setq source v1-localname)
2842 (when (string-match "\\([^#]*\\)#\\(.*\\)" v1-host)
2843 (setq copy-args (cons "-P" (cons (match-string 2 v1-host) copy-args)))
2844 (setq v1-host (match-string 1 v1-host)))
2845 (setq source
2846 (tramp-make-copy-program-file-name
2847 v1-user v1-host
2848 (tramp-shell-quote-argument v1-localname))))
2849
2850 (if (not t2)
2851 (setq target v2-localname)
2852 (when (string-match "\\([^#]*\\)#\\(.*\\)" v2-host)
2853 (setq copy-args (cons "-P" (cons (match-string 2 v2-host) copy-args)))
2854 (setq v2-host (match-string 1 v2-host)))
2855 (setq target
2856 (tramp-make-copy-program-file-name
2857 v2-user v2-host
2858 (tramp-shell-quote-argument v2-localname))))
2859
2860 ;; Handle keep-date argument
2861 (when keep-date
2862 (if t1
2863 (setq copy-args
2864 (cons (tramp-get-method-parameter
2865 v1-multi-method method
2866 v1-user v1-host 'tramp-copy-keep-date-arg)
2867 copy-args))
2868 (setq copy-args
2869 (cons (tramp-get-method-parameter
2870 v2-multi-method method
2871 v2-user v2-host 'tramp-copy-keep-date-arg)
2872 copy-args))))
2873
2874 (setq copy-args (append copy-args (list source target)))
2875
2876 ;; Use rcp-like program for file transfer.
2877 (tramp-message
2878 5 "Transferring %s to file %s..." filename newname)
2879 (save-excursion (set-buffer trampbuf) (erase-buffer))
2880 (unless (equal
2881 0
2882 (apply #'call-process copy-program
2883 nil trampbuf nil copy-args))
2884 (pop-to-buffer trampbuf)
2885 (error
2886 (concat
2887 "tramp-do-copy-or-rename-file-out-of-band: `%s' didn't work, "
2888 "see buffer `%s' for details")
2889 copy-program trampbuf))
2890 (tramp-message
2891 5 "Transferring %s to file %s...done" filename newname)
2892
2893 ;; If the operation was `rename', delete the original file.
2894 (unless (eq op 'copy)
2895 (delete-file filename))))
2686 2896
2687;; mkdir 2897;; mkdir
2688(defun tramp-handle-make-directory (dir &optional parents) 2898(defun tramp-handle-make-directory (dir &optional parents)
@@ -2745,7 +2955,6 @@ This is like `dired-recursive-delete-directory' for tramp files."
2745 (and (tramp-handle-file-exists-p filename) 2955 (and (tramp-handle-file-exists-p filename)
2746 (error "Failed to recusively delete %s" filename)))) 2956 (error "Failed to recusively delete %s" filename))))
2747 2957
2748
2749(defun tramp-handle-dired-call-process (program discard &rest arguments) 2958(defun tramp-handle-dired-call-process (program discard &rest arguments)
2750 "Like `dired-call-process' for tramp files." 2959 "Like `dired-call-process' for tramp files."
2751 (with-parsed-tramp-file-name default-directory nil 2960 (with-parsed-tramp-file-name default-directory nil
@@ -2767,6 +2976,59 @@ This is like `dired-recursive-delete-directory' for tramp files."
2767 (tramp-send-command-and-check multi-method method user host nil) 2976 (tramp-send-command-and-check multi-method method user host nil)
2768 (tramp-send-command multi-method method user host "cd") 2977 (tramp-send-command multi-method method user host "cd")
2769 (tramp-wait-for-output))))) 2978 (tramp-wait-for-output)))))
2979
2980(defun tramp-handle-dired-compress-file (file &rest ok-flag)
2981 "Like `dired-compress-file' for tramp files."
2982 ;; OK-FLAG is valid for XEmacs only, but not implemented.
2983 ;; Code stolen mainly from dired-aux.el.
2984 (with-parsed-tramp-file-name file nil
2985 (save-excursion
2986 (let ((suffixes
2987 (if (not (featurep 'xemacs))
2988 ;; Emacs case
2989 (symbol-value 'dired-compress-file-suffixes)
2990 ;; XEmacs has `dired-compression-method-alist', which is
2991 ;; transformed into `dired-compress-file-suffixes' structure.
2992 (mapcar
2993 '(lambda (x)
2994 (list (concat (regexp-quote (nth 1 x)) "\\'")
2995 nil
2996 (mapconcat 'identity (nth 3 x) " ")))
2997 (symbol-value 'dired-compression-method-alist))))
2998 suffix)
2999 ;; See if any suffix rule matches this file name.
3000 (while suffixes
3001 (let (case-fold-search)
3002 (if (string-match (car (car suffixes)) localname)
3003 (setq suffix (car suffixes) suffixes nil))
3004 (setq suffixes (cdr suffixes))))
3005
3006 (cond ((file-symlink-p file)
3007 nil)
3008 ((and suffix (nth 2 suffix))
3009 ;; We found an uncompression rule.
3010 (message "Uncompressing %s..." file)
3011 (when (zerop (tramp-send-command-and-check
3012 multi-method method user host
3013 (concat (nth 2 suffix) " " localname)))
3014 (message "Uncompressing %s...done" file)
3015 (dired-remove-file file)
3016 (string-match (car suffix) file)
3017 (concat (substring file 0 (match-beginning 0)))))
3018 (t
3019 ;; We don't recognize the file as compressed, so compress it.
3020 ;; Try gzip.
3021 (message "Compressing %s..." file)
3022 (when (zerop (tramp-send-command-and-check
3023 multi-method method user host
3024 (concat "gzip -f " localname)))
3025 (message "Compressing %s...done" file)
3026 (dired-remove-file file)
3027 (cond ((file-exists-p (concat file ".gz"))
3028 (concat file ".gz"))
3029 ((file-exists-p (concat file ".z"))
3030 (concat file ".z"))
3031 (t nil)))))))))
2770 3032
2771;; Pacify byte-compiler. The function is needed on XEmacs only. I'm 3033;; Pacify byte-compiler. The function is needed on XEmacs only. I'm
2772;; not sure at all that this is the right way to do it, but let's hope 3034;; not sure at all that this is the right way to do it, but let's hope
@@ -2961,17 +3223,40 @@ the result will be a local, non-Tramp, filename."
2961 3223
2962;; Remote commands. 3224;; Remote commands.
2963 3225
3226(defvar tramp-async-proc nil
3227 "Global variable keeping asyncronous process object.
3228Used in `tramp-handle-shell-command'")
3229
2964(defun tramp-handle-shell-command (command &optional output-buffer error-buffer) 3230(defun tramp-handle-shell-command (command &optional output-buffer error-buffer)
2965 "Like `shell-command' for tramp files. 3231 "Like `shell-command' for tramp files.
2966This will break if COMMAND prints a newline, followed by the value of 3232This will break if COMMAND prints a newline, followed by the value of
2967`tramp-end-of-output', followed by another newline." 3233`tramp-end-of-output', followed by another newline."
3234 ;; Asynchronous processes are far from being perfect. But it works at least
3235 ;; for `find-grep-dired' and `find-name-dired' in Emacs 21.4.
2968 (if (tramp-tramp-file-p default-directory) 3236 (if (tramp-tramp-file-p default-directory)
2969 (with-parsed-tramp-file-name default-directory nil 3237 (with-parsed-tramp-file-name default-directory nil
2970 (let (status) 3238 (let ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
2971 (when (string-match "&[ \t]*\\'" command) 3239 status)
2972 (error "Tramp doesn't grok asynchronous shell commands, yet")) 3240 (unless output-buffer
2973;; (when error-buffer 3241 (setq output-buffer
2974;; (error "Tramp doesn't grok optional third arg ERROR-BUFFER, yet")) 3242 (get-buffer-create
3243 (if asynchronous
3244 "*Async Shell Command*"
3245 "*Shell Command Output*")))
3246 (set-buffer output-buffer)
3247 (erase-buffer))
3248 (unless (bufferp output-buffer)
3249 (setq output-buffer (current-buffer)))
3250 (set-buffer output-buffer)
3251 ;; Tramp doesn't handle the asynchronous case by an asynchronous
3252 ;; process. Instead of, another asynchronous process is opened
3253 ;; which gets the output of the (synchronous) Tramp process
3254 ;; via process-filter. ERROR-BUFFER is disabled.
3255 (when asynchronous
3256 (setq command (substring command 0 (match-beginning 0))
3257 error-buffer nil
3258 tramp-async-proc (start-process (buffer-name output-buffer)
3259 output-buffer "cat")))
2975 (save-excursion 3260 (save-excursion
2976 (tramp-barf-unless-okay 3261 (tramp-barf-unless-okay
2977 multi-method method user host 3262 multi-method method user host
@@ -2979,23 +3264,39 @@ This will break if COMMAND prints a newline, followed by the value of
2979 nil 'file-error 3264 nil 'file-error
2980 "tramp-handle-shell-command: Couldn't `cd %s'" 3265 "tramp-handle-shell-command: Couldn't `cd %s'"
2981 (tramp-shell-quote-argument localname)) 3266 (tramp-shell-quote-argument localname))
3267 ;; Define the process filter
3268 (when asynchronous
3269 (set-process-filter
3270 (get-buffer-process
3271 (tramp-get-buffer multi-method method user host))
3272 '(lambda (process string)
3273 ;; Write the output into the Tramp Process
3274 (save-current-buffer
3275 (set-buffer (process-buffer process))
3276 (goto-char (point-max))
3277 (insert string))
3278 ;; Hand-over output to asynchronous process.
3279 (let ((end
3280 (string-match
3281 (regexp-quote tramp-end-of-output) string)))
3282 (when end
3283 (setq string
3284 (substring string 0 (1- (match-beginning 0)))))
3285 (process-send-string tramp-async-proc string)
3286 (when end
3287 (set-process-filter process nil)
3288 (process-send-eof tramp-async-proc))))))
3289 ;; Send the command
2982 (tramp-send-command 3290 (tramp-send-command
2983 multi-method method user host 3291 multi-method method user host
2984 (if error-buffer 3292 (if error-buffer
2985 (format "( %s ) 2>/tmp/tramp.$$.err; tramp_old_status=$?" 3293 (format "( %s ) 2>/tmp/tramp.$$.err; tramp_old_status=$?"
2986 command) 3294 command)
2987 (format "%s ;tramp_old_status=$?" command))) 3295 (format "%s; tramp_old_status=$?" command)))
2988 ;; This will break if the shell command prints "/////" 3296 (unless asynchronous
2989 ;; somewhere. Let's just hope for the best... 3297 (tramp-wait-for-output)))
2990 (tramp-wait-for-output)) 3298 (unless asynchronous
2991 (unless output-buffer 3299 (insert-buffer (tramp-get-buffer multi-method method user host)))
2992 (setq output-buffer (get-buffer-create "*Shell Command Output*"))
2993 (set-buffer output-buffer)
2994 (erase-buffer))
2995 (unless (bufferp output-buffer)
2996 (setq output-buffer (current-buffer)))
2997 (set-buffer output-buffer)
2998 (insert-buffer (tramp-get-buffer multi-method method user host))
2999 (when error-buffer 3300 (when error-buffer
3000 (save-excursion 3301 (save-excursion
3001 (unless (bufferp error-buffer) 3302 (unless (bufferp error-buffer)
@@ -3010,17 +3311,19 @@ This will break if COMMAND prints a newline, followed by the value of
3010 multi-method method user host "rm -f /tmp/tramp.$$.err"))) 3311 multi-method method user host "rm -f /tmp/tramp.$$.err")))
3011 (save-excursion 3312 (save-excursion
3012 (tramp-send-command multi-method method user host "cd") 3313 (tramp-send-command multi-method method user host "cd")
3013 (tramp-wait-for-output) 3314 (unless asynchronous
3315 (tramp-wait-for-output))
3014 (tramp-send-command 3316 (tramp-send-command
3015 multi-method method user host 3317 multi-method method user host
3016 (concat "tramp_set_exit_status $tramp_old_status;" 3318 (concat "tramp_set_exit_status $tramp_old_status;"
3017 " echo tramp_exit_status $?")) 3319 " echo tramp_exit_status $?"))
3018 (tramp-wait-for-output) 3320 (unless asynchronous
3019 (goto-char (point-max)) 3321 (tramp-wait-for-output)
3020 (unless (search-backward "tramp_exit_status " nil t) 3322 (goto-char (point-max))
3021 (error "Couldn't find exit status of `%s'" command)) 3323 (unless (search-backward "tramp_exit_status " nil t)
3022 (skip-chars-forward "^ ") 3324 (error "Couldn't find exit status of `%s'" command))
3023 (setq status (read (current-buffer)))) 3325 (skip-chars-forward "^ ")
3326 (setq status (read (current-buffer)))))
3024 (unless (zerop (buffer-size)) 3327 (unless (zerop (buffer-size))
3025 (display-buffer output-buffer)) 3328 (display-buffer output-buffer))
3026 status)) 3329 status))
@@ -3041,16 +3344,7 @@ This will break if COMMAND prints a newline, followed by the value of
3041(defun tramp-handle-file-local-copy (filename) 3344(defun tramp-handle-file-local-copy (filename)
3042 "Like `file-local-copy' for tramp files." 3345 "Like `file-local-copy' for tramp files."
3043 (with-parsed-tramp-file-name filename nil 3346 (with-parsed-tramp-file-name filename nil
3044 (let ((output-buf (get-buffer-create "*tramp output*")) 3347 (let ((tramp-buf (tramp-get-buffer multi-method method user host))
3045 (tramp-buf (tramp-get-buffer multi-method method user host))
3046 (copy-program (tramp-get-method-parameter
3047 multi-method
3048 (tramp-find-method multi-method method user host)
3049 user host 'tramp-copy-program))
3050 (copy-args (tramp-get-method-parameter
3051 multi-method
3052 (tramp-find-method multi-method method user host)
3053 user host 'tramp-copy-args))
3054 ;; We used to bind the following as late as possible. 3348 ;; We used to bind the following as late as possible.
3055 ;; loc-enc and loc-dec were bound directly before the if 3349 ;; loc-enc and loc-dec were bound directly before the if
3056 ;; statement that checks them. But the functions 3350 ;; statement that checks them. But the functions
@@ -3066,37 +3360,12 @@ This will break if COMMAND prints a newline, followed by the value of
3066 (error "Cannot make local copy of non-existing file `%s'" 3360 (error "Cannot make local copy of non-existing file `%s'"
3067 filename)) 3361 filename))
3068 (setq tmpfil (tramp-make-temp-file)) 3362 (setq tmpfil (tramp-make-temp-file))
3069 (cond (copy-program 3363
3070 ;; The following should be changed. We need a more general 3364
3071 ;; mechanism to parse extra host args. 3365 (cond ((tramp-method-out-of-band-p multi-method method user host)
3072 (when (string-match "\\([^#]*\\)#\\(.*\\)" host) 3366 ;; `copy-file' handles out-of-band methods
3073 (setq copy-args (cons "-p" (cons (match-string 2 host) 3367 (copy-file filename tmpfil t t))
3074 rsh-args))) 3368
3075 (setq host (match-string 1 host)))
3076 ;; Use rcp-like program for file transfer.
3077 (tramp-message-for-buffer
3078 multi-method method user host
3079 5 "Fetching %s to tmp file %s..." filename tmpfil)
3080 (save-excursion (set-buffer output-buf) (erase-buffer))
3081 (unless (equal
3082 0
3083 (apply #'call-process
3084 copy-program
3085 nil output-buf nil
3086 (append copy-args
3087 (list
3088 (tramp-make-copy-program-file-name
3089 user host
3090 (tramp-shell-quote-argument localname))
3091 tmpfil))))
3092 (pop-to-buffer output-buf)
3093 (error
3094 (concat "tramp-handle-file-local-copy: `%s' didn't work, "
3095 "see buffer `%s' for details")
3096 copy-program output-buf))
3097 (tramp-message-for-buffer
3098 multi-method method user host
3099 5 "Fetching %s to tmp file %s...done" filename tmpfil))
3100 ((and rem-enc rem-dec) 3369 ((and rem-enc rem-dec)
3101 ;; Use inline encoding for file transfer. 3370 ;; Use inline encoding for file transfer.
3102 (save-excursion 3371 (save-excursion
@@ -3225,14 +3494,6 @@ This will break if COMMAND prints a newline, followed by the value of
3225 (error "File not overwritten"))) 3494 (error "File not overwritten")))
3226 (with-parsed-tramp-file-name filename nil 3495 (with-parsed-tramp-file-name filename nil
3227 (let ((curbuf (current-buffer)) 3496 (let ((curbuf (current-buffer))
3228 (copy-program (tramp-get-method-parameter
3229 multi-method
3230 (tramp-find-method multi-method method user host)
3231 user host 'tramp-copy-program))
3232 (copy-args (tramp-get-method-parameter
3233 multi-method
3234 (tramp-find-method multi-method method user host)
3235 user host 'tramp-copy-args))
3236 (rem-enc (tramp-get-remote-encoding multi-method method user host)) 3497 (rem-enc (tramp-get-remote-encoding multi-method method user host))
3237 (rem-dec (tramp-get-remote-decoding multi-method method user host)) 3498 (rem-dec (tramp-get-remote-decoding multi-method method user host))
3238 (loc-enc (tramp-get-local-encoding multi-method method user host)) 3499 (loc-enc (tramp-get-local-encoding multi-method method user host))
@@ -3267,44 +3528,10 @@ This will break if COMMAND prints a newline, followed by the value of
3267 ;; decoding command must be specified. However, if the method 3528 ;; decoding command must be specified. However, if the method
3268 ;; _also_ specifies an encoding function, then that is used for 3529 ;; _also_ specifies an encoding function, then that is used for
3269 ;; encoding the contents of the tmp file. 3530 ;; encoding the contents of the tmp file.
3270 (cond (copy-program 3531 (cond ((tramp-method-out-of-band-p multi-method method user host)
3271 ;; The following should be changed. We need a more general 3532 ;; `copy-file' handles out-of-band methods
3272 ;; mechanism to parse extra host args. 3533 (copy-file tmpfil filename t t))
3273 (when (string-match "\\([^#]*\\)#\\(.*\\)" host) 3534
3274 (setq copy-args (cons "-p" (cons (match-string 2 host)
3275 rsh-args)))
3276 (setq host (match-string 1 host)))
3277
3278 ;; use rcp-like program for file transfer
3279 (let ((argl (append copy-args
3280 (list
3281 tmpfil
3282 (tramp-make-copy-program-file-name
3283 user host
3284 (tramp-shell-quote-argument localname))))))
3285 (tramp-message-for-buffer
3286 multi-method method user host
3287 6 "Writing tmp file using `%s'..." copy-program)
3288 (save-excursion (set-buffer trampbuf) (erase-buffer))
3289 (when tramp-debug-buffer
3290 (save-excursion
3291 (set-buffer (tramp-get-debug-buffer multi-method
3292 method user host))
3293 (goto-char (point-max))
3294 (tramp-insert-with-face
3295 'bold (format "$ %s %s\n" copy-program
3296 (mapconcat 'identity argl " ")))))
3297 (unless (equal 0
3298 (apply #'call-process
3299 copy-program nil trampbuf nil argl))
3300 (pop-to-buffer trampbuf)
3301 (error
3302 "Cannot write region to file `%s', command `%s' failed"
3303 filename copy-program))
3304 (tramp-message-for-buffer
3305 multi-method method user host
3306 6 "Transferring file using `%s'...done"
3307 copy-program)))
3308 ((and rem-enc rem-dec) 3535 ((and rem-enc rem-dec)
3309 ;; Use inline file transfer 3536 ;; Use inline file transfer
3310 (let ((tmpbuf (get-buffer-create " *tramp file transfer*"))) 3537 (let ((tmpbuf (get-buffer-create " *tramp file transfer*")))
@@ -3319,7 +3546,8 @@ This will break if COMMAND prints a newline, followed by the value of
3319 (progn 3546 (progn
3320 (tramp-message-for-buffer 3547 (tramp-message-for-buffer
3321 multi-method method user host 3548 multi-method method user host
3322 6 "Encoding region using function...") 3549 6 "Encoding region using function `%s'..."
3550 (symbol-name loc-enc))
3323 (insert-file-contents-literally tmpfil) 3551 (insert-file-contents-literally tmpfil)
3324 ;; CCC. The following `let' is a workaround for 3552 ;; CCC. The following `let' is a workaround for
3325 ;; the base64.el that comes with pgnus-0.84. If 3553 ;; the base64.el that comes with pgnus-0.84. If
@@ -3685,11 +3913,12 @@ necessary anymore."
3685;; shouldn't have partial tramp file name syntax. Maybe another variable should 3913;; shouldn't have partial tramp file name syntax. Maybe another variable should
3686;; be introduced overwriting this check in such cases. Or we change tramp 3914;; be introduced overwriting this check in such cases. Or we change tramp
3687;; file name syntax in order to avoid ambiguities, like in XEmacs ... 3915;; file name syntax in order to avoid ambiguities, like in XEmacs ...
3688;; In case of XEmacs it can be always true (and wouldn't be necessary). 3916;; In case of non unified file names it can be always true (and wouldn't be
3917;; necessary, because there are different regexp).
3689(defun tramp-completion-mode (file) 3918(defun tramp-completion-mode (file)
3690 "Checks whether method / user name / host name completion is active." 3919 "Checks whether method / user name / host name completion is active."
3691 (cond 3920 (cond
3692 ((featurep 'xemacs) t) 3921 ((not tramp-unified-filenames) t)
3693 ((string-match "^/.*:.*:$" file) nil) 3922 ((string-match "^/.*:.*:$" file) nil)
3694 ((string-match 3923 ((string-match
3695 (concat tramp-prefix-regexp 3924 (concat tramp-prefix-regexp
@@ -3697,11 +3926,21 @@ necessary anymore."
3697 file) 3926 file)
3698 (member (match-string 1 file) (mapcar 'car tramp-methods))) 3927 (member (match-string 1 file) (mapcar 'car tramp-methods)))
3699 ((or (equal last-input-event 'tab) 3928 ((or (equal last-input-event 'tab)
3929 ;; Emacs
3700 (and (integerp last-input-event) 3930 (and (integerp last-input-event)
3701 (not (event-modifiers last-input-event)) 3931 (not (event-modifiers last-input-event))
3702 (or (char-equal last-input-event ?\?) 3932 (or (char-equal last-input-event ?\?)
3703 (char-equal last-input-event ?\t) ; handled by 'tab already? 3933 (char-equal last-input-event ?\t) ; handled by 'tab already?
3704 (char-equal last-input-event ?\ )))) 3934 (char-equal last-input-event ?\ )))
3935 ;; XEmacs
3936 (and (featurep 'xemacs)
3937 (not (event-modifiers last-input-event))
3938 (or (char-equal
3939 (funcall 'event-to-character last-input-event) ?\?)
3940 (char-equal
3941 (funcall 'event-to-character last-input-event) ?\t)
3942 (char-equal
3943 (funcall 'event-to-character last-input-event) ?\ ))))
3705 t))) 3944 t)))
3706 3945
3707(defun tramp-completion-handle-file-exists-p (filename) 3946(defun tramp-completion-handle-file-exists-p (filename)
@@ -4050,6 +4289,35 @@ User is always nil."
4050 (forward-line 1)) 4289 (forward-line 1))
4051 result)) 4290 result))
4052 4291
4292(defun tramp-parse-shostkeys (dirname)
4293 "Return a list of (user host) tuples allowed to access.
4294User is always nil."
4295
4296 (let ((regexp (concat "^key_[0-9]+_\\(" tramp-host-regexp "\\)\\.pub$"))
4297 (files (when (file-directory-p dirname) (directory-files dirname)))
4298 result)
4299
4300 (while files
4301 (when (string-match regexp (car files))
4302 (push (list nil (match-string 1 (car files))) result))
4303 (setq files (cdr files)))
4304 result))
4305
4306(defun tramp-parse-sknownhosts (dirname)
4307 "Return a list of (user host) tuples allowed to access.
4308User is always nil."
4309
4310 (let ((regexp (concat "^\\(" tramp-host-regexp
4311 "\\)\\.ssh-\\(dss\\|rsa\\)\\.pub$"))
4312 (files (when (file-directory-p dirname) (directory-files dirname)))
4313 result)
4314
4315 (while files
4316 (when (string-match regexp (car files))
4317 (push (list nil (match-string 1 (car files))) result))
4318 (setq files (cdr files)))
4319 result))
4320
4053(defun tramp-parse-hosts (filename) 4321(defun tramp-parse-hosts (filename)
4054 "Return a list of (user host) tuples allowed to access. 4322 "Return a list of (user host) tuples allowed to access.
4055User is always nil." 4323User is always nil."
@@ -4206,14 +4474,29 @@ hosts, or files, disagree."
4206 (or switch "") 4474 (or switch "")
4207 (tramp-shell-quote-argument localname2)))))) 4475 (tramp-shell-quote-argument localname2))))))
4208 4476
4477(defun tramp-touch (file time)
4478 "Set the last-modified timestamp of the given file.
4479TIME is an Emacs internal time value as returned by `current-time'."
4480 (let ((touch-time (format-time-string "%Y%m%d%H%M.%S" time)))
4481 (with-parsed-tramp-file-name file nil
4482 (let ((buf (tramp-get-buffer multi-method method user host)))
4483 (unless (zerop (tramp-send-command-and-check
4484 multi-method method user host
4485 (format "touch -t %s %s"
4486 touch-time
4487 localname)))
4488 (pop-to-buffer buf)
4489 (error "tramp-touch: touch failed, see buffer `%s' for details"
4490 buf))))))
4491
4209(defun tramp-buffer-name (multi-method method user host) 4492(defun tramp-buffer-name (multi-method method user host)
4210 "A name for the connection buffer for USER at HOST using METHOD." 4493 "A name for the connection buffer for USER at HOST using METHOD."
4211 (if multi-method 4494 (if multi-method
4212 (tramp-buffer-name-multi-method "tramp" multi-method method user host) 4495 (tramp-buffer-name-multi-method "tramp" multi-method method user host)
4213 (let ((method (tramp-find-method multi-method method user host))) 4496 (let ((method (tramp-find-method multi-method method user host)))
4214 (if user 4497 (if user
4215 (format "*tramp/%s %s@%s*" method user host)) 4498 (format "*tramp/%s %s@%s*" method user host)
4216 (format "*tramp/%s %s*" method host)))) 4499 (format "*tramp/%s %s*" method host)))))
4217 4500
4218(defun tramp-buffer-name-multi-method (prefix multi-method method user host) 4501(defun tramp-buffer-name-multi-method (prefix multi-method method user host)
4219 "A name for the multi method connection buffer. 4502 "A name for the multi method connection buffer.
@@ -4482,11 +4765,6 @@ Returns nil if none was found, else the command is returned."
4482(defun tramp-action-password (p multi-method method user host) 4765(defun tramp-action-password (p multi-method method user host)
4483 "Query the user for a password." 4766 "Query the user for a password."
4484 (let ((pw-prompt (match-string 0))) 4767 (let ((pw-prompt (match-string 0)))
4485 (when (tramp-method-out-of-band-p multi-method method user host)
4486 (kill-process (get-buffer-process (current-buffer)))
4487 (error (concat "Out of band method `%s' not applicable "
4488 "for remote shell asking for a password")
4489 method))
4490 (tramp-message 9 "Sending password") 4768 (tramp-message 9 "Sending password")
4491 (tramp-enter-password p pw-prompt))) 4769 (tramp-enter-password p pw-prompt)))
4492 4770
@@ -4597,6 +4875,7 @@ The terminal type can be configured with `tramp-terminal-type'."
4597 p multi-method method user host actions) 4875 p multi-method method user host actions)
4598 nil))) 4876 nil)))
4599 (unless (eq exit 'ok) 4877 (unless (eq exit 'ok)
4878 (tramp-clear-passwd user host)
4600 (error "Login failed")))) 4879 (error "Login failed"))))
4601 4880
4602;; For multi-actions. 4881;; For multi-actions.
@@ -4632,6 +4911,7 @@ The terminal type can be configured with `tramp-terminal-type'."
4632 (tramp-process-one-multi-action p method user host actions) 4911 (tramp-process-one-multi-action p method user host actions)
4633 nil))) 4912 nil)))
4634 (unless (eq exit 'ok) 4913 (unless (eq exit 'ok)
4914 (tramp-clear-passwd user host)
4635 (error "Login failed")))) 4915 (error "Login failed"))))
4636 4916
4637;; Functions to execute when we have seen the remote shell prompt but 4917;; Functions to execute when we have seen the remote shell prompt but
@@ -4768,7 +5048,7 @@ arguments, and xx will be used as the host name to connect to.
4768 ;; The following should be changed. We need a more general 5048 ;; The following should be changed. We need a more general
4769 ;; mechanism to parse extra host args. 5049 ;; mechanism to parse extra host args.
4770 (when (string-match "\\([^#]*\\)#\\(.*\\)" host) 5050 (when (string-match "\\([^#]*\\)#\\(.*\\)" host)
4771 (setq login-args (cons "-p" (cons (match-string 2 host) rsh-args))) 5051 (setq login-args (cons "-p" (cons (match-string 2 host) login-args)))
4772 (setq host (match-string 1 host))) 5052 (setq host (match-string 1 host)))
4773 (setenv "TERM" tramp-terminal-type) 5053 (setenv "TERM" tramp-terminal-type)
4774 (let* ((default-directory (tramp-temporary-file-directory)) 5054 (let* ((default-directory (tramp-temporary-file-directory))
@@ -5308,10 +5588,7 @@ locale to C and sets up the remote shell search path."
5308 " -e '" tramp-perl-file-attributes "' $1 $2 2>/dev/null\n" 5588 " -e '" tramp-perl-file-attributes "' $1 $2 2>/dev/null\n"
5309 "}")) 5589 "}"))
5310 (tramp-wait-for-output) 5590 (tramp-wait-for-output)
5311 (unless (tramp-get-method-parameter 5591 (unless (tramp-method-out-of-band-p multi-method method user host)
5312 multi-method
5313 (tramp-find-method multi-method method user host)
5314 user host 'tramp-copy-program)
5315 (tramp-message 5 "Sending the Perl `mime-encode' implementations.") 5592 (tramp-message 5 "Sending the Perl `mime-encode' implementations.")
5316 (tramp-send-string 5593 (tramp-send-string
5317 multi-method method user host 5594 multi-method method user host
@@ -5350,10 +5627,7 @@ locale to C and sets up the remote shell search path."
5350 (tramp-set-connection-property "ln" ln multi-method method user host))) 5627 (tramp-set-connection-property "ln" ln multi-method method user host)))
5351 (erase-buffer) 5628 (erase-buffer)
5352 ;; Find the right encoding/decoding commands to use. 5629 ;; Find the right encoding/decoding commands to use.
5353 (unless (tramp-get-method-parameter 5630 (unless (tramp-method-out-of-band-p multi-method method user host)
5354 multi-method
5355 (tramp-find-method multi-method method user host)
5356 user host 'tramp-copy-program)
5357 (tramp-find-inline-encoding multi-method method user host)) 5631 (tramp-find-inline-encoding multi-method method user host))
5358 ;; If encoding/decoding command are given, test to see if they work. 5632 ;; If encoding/decoding command are given, test to see if they work.
5359 ;; CCC: Maybe it would be useful to run the encoder both locally and 5633 ;; CCC: Maybe it would be useful to run the encoder both locally and
@@ -5566,11 +5840,12 @@ connection if a previous connection has died for some reason."
5566 (unless (and p (processp p) (memq (process-status p) '(run open))) 5840 (unless (and p (processp p) (memq (process-status p) '(run open)))
5567 (when (and p (processp p)) 5841 (when (and p (processp p))
5568 (delete-process p)) 5842 (delete-process p))
5569 (funcall (tramp-get-method-parameter 5843 (let ((process-connection-type tramp-process-connection-type))
5570 multi-method 5844 (funcall (tramp-get-method-parameter
5571 (tramp-find-method multi-method method user host) 5845 multi-method
5572 user host 'tramp-connection-function) 5846 (tramp-find-method multi-method method user host)
5573 multi-method method user host)))) 5847 user host 'tramp-connection-function)
5848 multi-method method user host)))))
5574 5849
5575(defun tramp-send-command 5850(defun tramp-send-command
5576 (multi-method method user host command &optional noerase neveropen) 5851 (multi-method method user host command &optional noerase neveropen)
@@ -6223,10 +6498,28 @@ this is the function `temp-directory'."
6223 6498
6224(defun tramp-read-passwd (prompt) 6499(defun tramp-read-passwd (prompt)
6225 "Read a password from user (compat function). 6500 "Read a password from user (compat function).
6226Invokes `read-passwd' if that is defined, else `ange-ftp-read-passwd'." 6501Invokes `password-read' if available, `read-passwd' else."
6227 (apply 6502 (if (functionp 'password-read)
6228 (if (fboundp 'read-passwd) #'read-passwd #'ange-ftp-read-passwd) 6503 (let* ((user (or tramp-current-user (user-login-name)))
6229 (list prompt))) 6504 (host (or tramp-current-host (system-name)))
6505 (key (concat user "@" host))
6506 (password (apply #'password-read (list prompt key))))
6507 (apply #'password-cache-add (list key password))
6508 password)
6509 (read-passwd prompt)))
6510
6511(defun tramp-clear-passwd (&optional user host)
6512 "Clear password cache for connection related to current-buffer."
6513 (interactive)
6514 (let ((filename (or buffer-file-name list-buffers-directory "")))
6515 (when (and (functionp 'password-cache-remove)
6516 (or (and user host) (tramp-tramp-file-p filename)))
6517 (let* ((v (when (tramp-tramp-file-p filename)
6518 (tramp-dissect-file-name filename)))
6519 (luser (or user (tramp-file-name-user v) (user-login-name)))
6520 (lhost (or host (tramp-file-name-host v) (system-name)))
6521 (key (concat luser "@" lhost)))
6522 (apply #'password-cache-remove (list key))))))
6230 6523
6231(defun tramp-time-diff (t1 t2) 6524(defun tramp-time-diff (t1 t2)
6232 "Return the difference between the two times, in seconds. 6525 "Return the difference between the two times, in seconds.
@@ -6477,7 +6770,6 @@ report.
6477 6770
6478;;; TODO: 6771;;; TODO:
6479 6772
6480;; * tramp-copy-keep-date-arg is not used!
6481;; * Allow putting passwords in the filename. 6773;; * Allow putting passwords in the filename.
6482;; This should be implemented via a general mechanism to add 6774;; This should be implemented via a general mechanism to add
6483;; parameters in filenames. There is currently a kludge for 6775;; parameters in filenames. There is currently a kludge for
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 72c8c97899a..b3223d7a46e 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -30,7 +30,7 @@
30;; are auto-frobbed from configure.ac, so you should edit that file and run 30;; are auto-frobbed from configure.ac, so you should edit that file and run
31;; "autoconf && ./configure" to change them. 31;; "autoconf && ./configure" to change them.
32 32
33(defconst tramp-version "2.0.38" 33(defconst tramp-version "2.0.39"
34 "This version of Tramp.") 34 "This version of Tramp.")
35 35
36(defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org" 36(defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org"