diff options
| author | Kai Großjohann | 2004-02-29 17:52:17 +0000 |
|---|---|---|
| committer | Kai Großjohann | 2004-02-29 17:52:17 +0000 |
| commit | 5ec2cc41db095268a8597af7705bfc3d156b99db (patch) | |
| tree | 0dcf5f2e73da2e610f04417e80290c58f314e814 /lisp | |
| parent | cc86f83f38c5c9ffbe8ac6a2a5ba35b9e9080a93 (diff) | |
| download | emacs-5ec2cc41db095268a8597af7705bfc3d156b99db.tar.gz emacs-5ec2cc41db095268a8597af7705bfc3d156b99db.zip | |
Tramp: sync with upstream version 2.0.39.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 99 | ||||
| -rw-r--r-- | lisp/net/tramp-ftp.el | 17 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 137 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 766 | ||||
| -rw-r--r-- | lisp/net/trampver.el | 2 |
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 @@ | |||
| 1 | 2004-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 | |||
| 17 | 2004-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 | |||
| 1 | 2004-02-28 Richard M. Stallman <rms@gnu.org> | 100 | 2004-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. |
| 93 | Used instead of analyzing error codes of commands.") | 96 | Used instead of analyzing error codes of commands.") |
| @@ -102,12 +105,6 @@ This variable is local to each buffer.") | |||
| 102 | This variable is local to each buffer.") | 105 | This 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. | ||
| 107 | Will be changed by corresponding `process-sentinel'. | ||
| 108 | This 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'. |
| 914 | Does not do anything if a connection is already open, but re-opens the | 918 | Does not do anything if a connection is already open, but re-opens the |
| 915 | connection if a previous connection has died for some reason." | 919 | connection 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. |
| 1009 | Sets position to begin of buffer. | ||
| 1010 | Returns nil if an error message has appeared." | 1011 | Returns 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. |
| 682 | This is a list of entries of the form (NAME PAIR1 PAIR2 ...). | 665 | This is a list of entries of the form (NAME PAIR1 PAIR2 ...). |
| 683 | Each NAME stands for a remote access method. Each PAIR is of the form | 666 | Each 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 |
| 685 | names from FILE for completion. The following predefined FUNCTIONs exists: | 668 | names 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. | |
| 694 | FUNCTION can also see a customer defined function. For more details see | 677 | * `tramp-parse-netrc' for \"~/.netrc\" like files. |
| 695 | the info pages." | 678 | |
| 696 | :group 'tramp | 679 | FUNCTION can also be a customer defined function. For more details see |
| 697 | :type '(repeat | 680 | the 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. | ||
| 1312 | Tramp binds process-connection-type to the value given here before | ||
| 1313 | opening 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. |
| 1771 | For definition of that list see `tramp-set-completion-function'." | 1834 | For 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." | |||
| 2634 | First arg OP is either `copy' or `rename' and indicates the operation. | 2739 | First arg OP is either `copy' or `rename' and indicates the operation. |
| 2635 | FILENAME is the source file, NEWNAME the target file. | 2740 | FILENAME is the source file, NEWNAME the target file. |
| 2636 | KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." | 2741 | KEEP-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. |
| 2682 | One of FILENAME and NEWNAME must be a Tramp name, the other must | 2792 | One of FILENAME and NEWNAME must be a Tramp name, the other must |
| 2683 | be a local filename. The method used must be an out-of-band method." | 2793 | be 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. | ||
| 3228 | Used 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. |
| 2966 | This will break if COMMAND prints a newline, followed by the value of | 3232 | This 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. | ||
| 4294 | User 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. | ||
| 4308 | User 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. |
| 4055 | User is always nil." | 4323 | User 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. | ||
| 4479 | TIME 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). |
| 6226 | Invokes `read-passwd' if that is defined, else `ange-ftp-read-passwd'." | 6501 | Invokes `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" |