diff options
Diffstat (limited to 'lisp/net')
-rw-r--r-- | lisp/net/ange-ftp.el | 31 | ||||
-rw-r--r-- | lisp/net/browse-url.el | 51 | ||||
-rw-r--r-- | lisp/net/eudc-bob.el | 1 | ||||
-rw-r--r-- | lisp/net/eudc-export.el | 1 | ||||
-rw-r--r-- | lisp/net/eudc-hotlist.el | 1 | ||||
-rw-r--r-- | lisp/net/eudc-vars.el | 1 | ||||
-rw-r--r-- | lisp/net/eudc.el | 1 | ||||
-rw-r--r-- | lisp/net/eudcb-bbdb.el | 1 | ||||
-rw-r--r-- | lisp/net/eudcb-ldap.el | 1 | ||||
-rw-r--r-- | lisp/net/eudcb-ph.el | 1 | ||||
-rw-r--r-- | lisp/net/goto-addr.el | 1 | ||||
-rw-r--r-- | lisp/net/ldap.el | 26 | ||||
-rw-r--r-- | lisp/net/net-utils.el | 1 | ||||
-rw-r--r-- | lisp/net/netrc.el | 1 | ||||
-rw-r--r-- | lisp/net/quickurl.el | 1 | ||||
-rw-r--r-- | lisp/net/rcompile.el | 1 | ||||
-rw-r--r-- | lisp/net/rlogin.el | 3 | ||||
-rw-r--r-- | lisp/net/snmp-mode.el | 1 | ||||
-rw-r--r-- | lisp/net/telnet.el | 3 | ||||
-rw-r--r-- | lisp/net/tls.el | 1 | ||||
-rw-r--r-- | lisp/net/tramp-ftp.el | 20 | ||||
-rw-r--r-- | lisp/net/tramp-smb.el | 162 | ||||
-rw-r--r-- | lisp/net/tramp-util.el | 2 | ||||
-rw-r--r-- | lisp/net/tramp-uu.el | 2 | ||||
-rw-r--r-- | lisp/net/tramp-vc.el | 12 | ||||
-rw-r--r-- | lisp/net/tramp.el | 925 | ||||
-rw-r--r-- | lisp/net/trampver.el | 3 | ||||
-rw-r--r-- | lisp/net/webjump.el | 6 | ||||
-rw-r--r-- | lisp/net/zone-mode.el | 3 |
29 files changed, 794 insertions, 470 deletions
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index a315482fd1e..8e1068a5bed 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -686,7 +686,7 @@ :prefix "ange-ftp-") (defcustom ange-ftp-name-format - '("^/\\(\\([^@/:]*\\)@\\)?\\([^@/:]*[^@/:.]\\):\\(.*\\)" . (3 2 4)) + '("^/\\(\\([^/:]*\\)@\\)?\\([^@/:]*[^@/:.]\\):\\(.*\\)" . (3 2 4)) "*Format of a fully expanded remote file name. This is a list of the form \(REGEXP HOST USER NAME\), @@ -694,7 +694,7 @@ where REGEXP is a regular expression matching the full remote name, and HOST, USER, and NAME are the numbers of parenthesized expressions in REGEXP for the components (in that order)." :group 'ange-ftp - :type '(list regexp + :type '(list (regexp :tag "Name regexp") (integer :tag "Host group") (integer :tag "User group") (integer :tag "Name group"))) @@ -1469,14 +1469,15 @@ only return the directory part of FILE." ;; Display the last chunk of output from the ftp process for the given HOST ;; USER pair, and signal an error including MSG in the text. (defun ange-ftp-error (host user msg) - (let ((cur (selected-window)) - (pop-up-windows t)) - (pop-to-buffer - (get-buffer-create - (ange-ftp-ftp-process-buffer host user))) - (goto-char (point-max)) - (select-window cur)) - (signal 'ftp-error (list (format "FTP Error: %s" msg)))) + (save-excursion ;; Prevent pop-to-buffer from changing current buffer. + (let ((cur (selected-window)) + (pop-up-windows t)) + (pop-to-buffer + (get-buffer-create + (ange-ftp-ftp-process-buffer host user))) + (goto-char (point-max)) + (select-window cur)) + (signal 'ftp-error (list (format "FTP Error: %s" msg))))) (defun ange-ftp-set-buffer-mode () "Set correct modes for the current buffer if visiting a remote file." @@ -1917,7 +1918,8 @@ on the gateway machine to do the ftp instead." ;; but that doesn't work: ftp never responds. ;; Can anyone find a fix for that? (let ((process-connection-type t) - (process-environment process-environment) + ;; Copy this so we don't alter it permanently. + (process-environment (copy-tree process-environment)) (buffer (get-buffer-create name))) (save-excursion (set-buffer buffer) @@ -3433,7 +3435,7 @@ system TYPE.") (nreverse files))) (apply 'ange-ftp-real-directory-files directory full match v19-args))) -(defun ange-ftp-file-attributes (file) +(defun ange-ftp-file-attributes (file &optional id-format) (setq file (expand-file-name file)) (let ((parsed (ange-ftp-ftp-name file))) (if parsed @@ -3466,7 +3468,9 @@ system TYPE.") inode ;10 "inode number". -1 ;11 device number [v19 only] )))) - (ange-ftp-real-file-attributes file)))) + (if id-format + (ange-ftp-real-file-attributes file id-format) + (ange-ftp-real-file-attributes file))))) (defun ange-ftp-file-newer-than-file-p (f1 f2) (let ((f1-parsed (ange-ftp-ftp-name f1)) @@ -6048,4 +6052,5 @@ be recognized automatically (they are all valid BS2000 hosts too)." (provide 'ange-ftp) +;;; arch-tag: 2987ef88-cb56-4ec1-87a9-79132572e316 ;;; ange-ftp.el ends here diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index b97eda6472b..a70e08028d2 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -1,6 +1,6 @@ ;;; browse-url.el --- pass a URL to a WWW browser -;; Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 +;; Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001, 2004 ;; Free Software Foundation, Inc. ;; Author: Denis Howe <dbh@doc.ic.ac.uk> @@ -818,8 +818,8 @@ When called non-interactively, optional second argument NEW-WINDOW is used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) ;; URL encode any `confusing' characters in the URL. This needs to - ;; include at least commas; presumably also close parens. - (while (string-match "[,)]" url) + ;; include at least commas; presumably also close parens and dollars. + (while (string-match "[,)$]" url) (setq url (replace-match (format "%%%x" (string-to-char (match-string 0 url))) t t url))) (let* ((process-environment (browse-url-process-environment)) @@ -889,8 +889,8 @@ When called non-interactively, optional second argument NEW-WINDOW is used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) ;; URL encode any `confusing' characters in the URL. This needs to - ;; include at least commas; presumably also close parens. - (while (string-match "[,)]" url) + ;; include at least commas; presumably also close parens and dollars. + (while (string-match "[,)$]" url) (setq url (replace-match (format "%%%x" (string-to-char (match-string 0 url))) t t url))) (let* ((process-environment (browse-url-process-environment)) @@ -942,8 +942,8 @@ When called non-interactively, optional second argument NEW-WINDOW is used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) ;; URL encode any `confusing' characters in the URL. This needs to - ;; include at least commas; presumably also close parens. - (while (string-match "[,)]" url) + ;; include at least commas; presumably also close parens and dollars. + (while (string-match "[,)$]" url) (setq url (replace-match (format "%%%x" (string-to-char (match-string 0 url))) t t url))) (let* ((process-environment (browse-url-process-environment)) @@ -991,8 +991,8 @@ When called non-interactively, optional second argument NEW-WINDOW is used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "URL: ")) ;; URL encode any `confusing' characters in the URL. This needs to - ;; include at least commas; presumably also close parens. - (while (string-match "[,)]" url) + ;; include at least commas; presumably also close parens and dollars. + (while (string-match "[,)$]" url) (setq url (replace-match (format "%%%x" (string-to-char (match-string 0 url))) t t url))) (let* ((process-environment (browse-url-process-environment)) @@ -1301,9 +1301,11 @@ Default to the URL around or before point." ;; --- mailto --- +(autoload 'rfc2368-parse-mailto-url "rfc2368") + ;;;###autoload (defun browse-url-mail (url &optional new-window) - "Open a new mail message buffer within Emacs. + "Open a new mail message buffer within Emacs for the RFC 2368 URL. Default to using the mailto: URL around or before point as the recipient's address. Supplying a non-nil interactive prefix argument will cause the mail to be composed in another window rather than the @@ -1318,14 +1320,24 @@ When called non-interactively, optional second argument NEW-WINDOW is used instead of `browse-url-new-window-flag'." (interactive (browse-url-interactive-arg "Mailto URL: ")) (save-excursion - (let ((to (if (string-match "^mailto:" url) - (substring url 7) - url))) + (let* ((alist (rfc2368-parse-mailto-url url)) + (to (assoc "To" alist)) + (subject (assoc "Subject" alist)) + (body (assoc "Body" alist)) + (rest (delete to (delete subject (delete body alist)))) + (to (cdr to)) + (subject (cdr subject)) + (body (cdr body)) + (mail-citation-hook (unless body mail-citation-hook))) (if (browse-url-maybe-new-window new-window) - (compose-mail-other-window to nil nil nil - (list 'insert-buffer (current-buffer))) - (compose-mail to nil nil nil nil - (list 'insert-buffer (current-buffer))))))) + (compose-mail-other-window to subject rest nil + (if body + (list 'insert body) + (list 'insert-buffer (current-buffer)))) + (compose-mail to subject rest nil nil + (if body + (list 'insert body) + (list 'insert-buffer (current-buffer)))))))) ;; --- Random browser --- @@ -1340,8 +1352,8 @@ don't offer a form of remote control." (interactive (browse-url-interactive-arg "URL: ")) (if (not browse-url-generic-program) (error "No browser defined (`browse-url-generic-program')")) - (apply 'start-process (concat browse-url-generic-program url) nil - browse-url-generic-program + (apply 'call-process browse-url-generic-program nil + 0 nil (append browse-url-generic-args (list url)))) ;;;###autoload @@ -1355,4 +1367,5 @@ Default to the URL around or before point." (provide 'browse-url) +;;; arch-tag: d2079573-5c06-4097-9598-f550fba19430 ;;; browse-url.el ends here diff --git a/lisp/net/eudc-bob.el b/lisp/net/eudc-bob.el index 78593fe5c19..df20007cfb7 100644 --- a/lisp/net/eudc-bob.el +++ b/lisp/net/eudc-bob.el @@ -365,4 +365,5 @@ display a button." "Display a button for the JPEG DATA." (eudc-bob-display-jpeg data nil)) +;;; arch-tag: 8f1853df-c9b6-4c5a-bdb1-d94dbd651fb3 ;;; eudc-bob.el ends here diff --git a/lisp/net/eudc-export.el b/lisp/net/eudc-export.el index 9bd3ad7ca7e..704792f6b68 100644 --- a/lisp/net/eudc-export.el +++ b/lisp/net/eudc-export.el @@ -215,4 +215,5 @@ This function can only be called from a directory query result buffer." (overlay-get (car (overlays-at (point))) 'eudc-record) (eudc-insert-record-at-point-into-bbdb))) +;;; arch-tag: 8cbda7dc-3163-47e6-921c-6ec5083df2d7 ;;; eudc-export.el ends here diff --git a/lisp/net/eudc-hotlist.el b/lisp/net/eudc-hotlist.el index c03cf0219f8..9dc81ce2bc9 100644 --- a/lisp/net/eudc-hotlist.el +++ b/lisp/net/eudc-hotlist.el @@ -194,4 +194,5 @@ These are the special commands of this mode: "" eudc-hotlist-menu)) +;;; arch-tag: 9b633ab3-6a6e-4b46-b12e-d96739a7e0e8 ;;; eudc-hotlist.el ends here diff --git a/lisp/net/eudc-vars.el b/lisp/net/eudc-vars.el index b44f7f74607..1b9da92da67 100644 --- a/lisp/net/eudc-vars.el +++ b/lisp/net/eudc-vars.el @@ -406,4 +406,5 @@ Otherwise records must match queries exactly." (provide 'eudc-vars) +;;; arch-tag: 80050575-b838-4246-8ebc-b2d7c5a2e482 ;;; eudc-vars.el ends here diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el index 9d3e4aa9d34..6d12d5e6364 100644 --- a/lisp/net/eudc.el +++ b/lisp/net/eudc.el @@ -1284,4 +1284,5 @@ This does nothing except loading eudc by autoload side-effect." (provide 'eudc) +;;; arch-tag: e18872b6-db83-400b-869d-be54e9a4160c ;;; eudc.el ends here diff --git a/lisp/net/eudcb-bbdb.el b/lisp/net/eudcb-bbdb.el index 1c20c7cc185..745d6e289a1 100644 --- a/lisp/net/eudcb-bbdb.el +++ b/lisp/net/eudcb-bbdb.el @@ -231,4 +231,5 @@ RETURN-ATTRS is a list of attributes to return, defaulting to (provide 'eudcb-bbdb) +;;; arch-tag: 38276208-75de-4dbc-ba6f-8db684c32e0a ;;; eudcb-bbdb.el ends here diff --git a/lisp/net/eudcb-ldap.el b/lisp/net/eudcb-ldap.el index fb97bc754e7..a206578b774 100644 --- a/lisp/net/eudcb-ldap.el +++ b/lisp/net/eudcb-ldap.el @@ -208,4 +208,5 @@ attribute names are returned. Default to `person'" (provide 'eudcb-ldap) +;;; arch-tag: 0f254dc0-7378-4fd4-ae26-18666184e96b ;;; eudcb-ldap.el ends here diff --git a/lisp/net/eudcb-ph.el b/lisp/net/eudcb-ph.el index 68d03979f48..efd89beaaa9 100644 --- a/lisp/net/eudcb-ph.el +++ b/lisp/net/eudcb-ph.el @@ -244,4 +244,5 @@ depending on RETURN-RESPONSE." (provide 'eudcb-ph) +;;; arch-tag: 4365bbf5-af20-453e-b5b6-2e7118ebfcdb ;;; eudcb-ph.el ends here diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el index 1449c9bcc38..b77be84deb3 100644 --- a/lisp/net/goto-addr.el +++ b/lisp/net/goto-addr.el @@ -248,4 +248,5 @@ Also fontifies the buffer appropriately (see `goto-address-fontify-p' and (provide 'goto-addr) +;;; arch-tag: ca47c505-5661-425d-a471-62bc6e75cf0a ;;; goto-addr.el ends here diff --git a/lisp/net/ldap.el b/lisp/net/ldap.el index d539164e9f9..55af47e6a87 100644 --- a/lisp/net/ldap.el +++ b/lisp/net/ldap.el @@ -1,6 +1,6 @@ ;;; ldap.el --- client interface to LDAP for Emacs -;; Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 02, 2004 Free Software Foundation, Inc. ;; Author: Oscar Figueiredo <oscar@cpe.fr> ;; Maintainer: Pavel Janík <Pavel@Janik.cz> @@ -36,6 +36,7 @@ ;;; Code: (require 'custom) +(eval-when-compile (require 'cl)) (defgroup ldap nil "Lightweight Directory Access Protocol." @@ -464,17 +465,16 @@ Additional search parameters can be specified through (error "No LDAP host specified")) (let ((host-plist (cdr (assoc host ldap-host-parameters-alist))) result) - (setq result (ldap-search-internal (append host-plist - (list 'host host - 'filter filter - 'attributes attributes - 'attrsonly attrsonly - 'withdn withdn)))) + (setq result (ldap-search-internal (list* 'host host + 'filter filter + 'attributes attributes + 'attrsonly attrsonly + 'withdn withdn + host-plist))) (if ldap-ignore-attribute-codings result - (mapcar (function - (lambda (record) - (mapcar 'ldap-decode-attribute record))) + (mapcar (lambda (record) + (mapcar 'ldap-decode-attribute record)) result)))) @@ -582,6 +582,11 @@ an alist of attribute/value pairs." (while (looking-at "^\\(\\w*\\)[=:\t ]+\\(<[\t ]*file://\\)?\\(.*\\)$") (setq name (match-string 1) value (match-string 3)) + ;; Need to handle file:///D:/... as generated by OpenLDAP + ;; on DOS/Windows as local files. + (if (and (memq system-type '(windows-nt ms-dos)) + (eq (string-match "/\\(.:.*\\)$" value) 0)) + (setq value (match-string 1 value))) ;; Do not try to open non-existent files (if (equal value "") (setq value " ") @@ -607,4 +612,5 @@ an alist of attribute/value pairs." (provide 'ldap) +;;; arch-tag: 47913a76-6155-42e6-ac58-6d28b5d50eb0 ;;; ldap.el ends here diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el index 982923ed559..202dac361e7 100644 --- a/lisp/net/net-utils.el +++ b/lisp/net/net-utils.el @@ -828,4 +828,5 @@ from SEARCH-STRING. With argument, prompt for whois server." (provide 'net-utils) +;;; arch-tag: 97119e91-9edb-4376-838b-bf7058fa1314 ;;; net-utils.el ends here diff --git a/lisp/net/netrc.el b/lisp/net/netrc.el index 8062b4292dc..713c036ce7b 100644 --- a/lisp/net/netrc.el +++ b/lisp/net/netrc.el @@ -125,4 +125,5 @@ Entries without port tokens default to DEFAULTPORT." (provide 'netrc) +;;; arch-tag: af9929cc-2d12-482f-936e-eb4366f9fa55 ;;; netrc.el ends here diff --git a/lisp/net/quickurl.el b/lisp/net/quickurl.el index 22794a41078..fd13b3a0f51 100644 --- a/lisp/net/quickurl.el +++ b/lisp/net/quickurl.el @@ -549,4 +549,5 @@ TYPE dictates what will be inserted, options are: (provide 'quickurl) +;;; arch-tag: a8183ea5-80c2-4082-a7d1-b0fdf2da467e ;;; quickurl.el ends here diff --git a/lisp/net/rcompile.el b/lisp/net/rcompile.el index 8105593c758..c9078ac2d76 100644 --- a/lisp/net/rcompile.el +++ b/lisp/net/rcompile.el @@ -175,4 +175,5 @@ See \\[compile]." (set (make-local-variable 'comint-file-name-prefix) (concat "/" host ":"))))) +;;; arch-tag: 2866a132-ece4-4ce9-9f91-ec147f803f73 ;;; rcompile.el ends here diff --git a/lisp/net/rlogin.el b/lisp/net/rlogin.el index cc2defdf166..fa7e0d1950e 100644 --- a/lisp/net/rlogin.el +++ b/lisp/net/rlogin.el @@ -6,8 +6,6 @@ ;; Maintainer: Noah Friedman <friedman@splode.com> ;; Keywords: unix, comm -;; $Id: rlogin.el,v 1.3 2002/03/14 11:51:47 miles Exp $ - ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify @@ -329,4 +327,5 @@ Delete ARG characters forward, or send a C-d to process if at end of buffer." (provide 'rlogin) +;;; arch-tag: 6e20eabf-feda-40fa-ab40-0d156db447e4 ;;; rlogin.el ends here diff --git a/lisp/net/snmp-mode.el b/lisp/net/snmp-mode.el index cde6fb7c60d..7fed47f6bf8 100644 --- a/lisp/net/snmp-mode.el +++ b/lisp/net/snmp-mode.el @@ -720,4 +720,5 @@ controls whether case is significant." (provide 'snmp-mode) +;;; arch-tag: eb6cc0f9-1e47-4023-8625-bc9aae6c3527 ;;; snmp-mode.el ends here diff --git a/lisp/net/telnet.el b/lisp/net/telnet.el index b75ff47220d..dac6f228cd6 100644 --- a/lisp/net/telnet.el +++ b/lisp/net/telnet.el @@ -89,8 +89,8 @@ Should be set to the number of terminal writes telnet will make rejecting one login and prompting again for a username and password.") (defun telnet-interrupt-subjob () - (interactive) "Interrupt the program running through telnet on the remote host." + (interactive) (send-string nil telnet-interrupt-string)) (defun telnet-c-z () @@ -262,4 +262,5 @@ Normally input is edited in Emacs and sent a line at a time." (provide 'telnet) +;;; arch-tag: 98218821-d04a-48b6-9058-57d0d4677a56 ;;; telnet.el ends here diff --git a/lisp/net/tls.el b/lisp/net/tls.el index 70270773a3c..dd161032d9a 100644 --- a/lisp/net/tls.el +++ b/lisp/net/tls.el @@ -124,4 +124,5 @@ specifying a port number to connect to." (provide 'tls) +;;; arch-tag: 5596d1c4-facc-4bc4-94a9-9863b928d7ac ;;; tls.el ends here diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el index 07a756c3523..3be891a49f8 100644 --- a/lisp/net/tramp-ftp.el +++ b/lisp/net/tramp-ftp.el @@ -1,6 +1,6 @@ ;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP and EFS -*- coding: iso-8859-1; -*- -;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Michael Albinus <Michael.Albinus@alcatel.de> ;; Keywords: comm, processes @@ -24,8 +24,8 @@ ;;; Commentary: -;; Convenience functions for calling Ange-FTP (and maybe EFS, later on) -;; from Tramp. Most of them are displaced from tramp.el. +;; Convenience functions for calling Ange-FTP from Tramp. +;; Most of them are displaced from tramp.el. ;;; Code: @@ -98,9 +98,16 @@ pass to the OPERATION." (list (nth 0 tramp-file-name-structure) (nth 3 tramp-file-name-structure) (nth 2 tramp-file-name-structure) - (nth 4 tramp-file-name-structure)))) + (nth 4 tramp-file-name-structure))) + ;; ange-ftp uses `ange-ftp-ftp-name-arg' and `ange-ftp-ftp-name-res' + ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active, + ;; there could be incorrect values from previous calls in case the + ;; "ftp" method is used in the Tramp file name. So we unset + ;; those values. + (ange-ftp-ftp-name-arg "") + (ange-ftp-ftp-name-res nil)) (cond - ;; If argument is a symlink, 'file-directory-p` and 'file-exists-p` + ;; If argument is a symlink, `file-directory-p' and `file-exists-p' ;; call the traversed file recursively. So we cannot disable the ;; file-name-handler this case. ((memq operation '(file-directory-p file-exists-p)) @@ -137,5 +144,8 @@ pass to the OPERATION." ;; pretended in `tramp-file-name-handler' otherwise. ;; Furthermore, there are no backup files on FTP hosts. ;; Worth further investigations. +;; * Map /multi:ssh:out@gate:ftp:kai@real.host:/path/to.file +;; on Ange-FTP gateways. +;;; arch-tag: 759fb338-5c63-4b99-bd36-b4d59db91cff ;;; tramp-ftp.el ends here diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 8474b7a88a3..ab6ad3310c1 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -1,6 +1,6 @@ ;;; tramp-smb.el --- Tramp access functions for SMB servers -*- coding: iso-8859-1; -*- -;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Michael Albinus <Michael.Albinus@alcatel.de> ;; Keywords: comm, processes @@ -50,7 +50,7 @@ ;; Add a default for `tramp-default-method-alist'. Rule: If there is ;; a domain in USER, it must be the SMB method. (add-to-list 'tramp-default-method-alist - (list "%" "" tramp-smb-method)) + (list "" "%" tramp-smb-method)) ;; Add completion function for SMB method. (tramp-set-completion-function @@ -62,7 +62,7 @@ :group 'tramp :type 'string) -(defconst tramp-smb-prompt "^smb: \\S-+> " +(defconst tramp-smb-prompt "^smb: \\S-+> \\|^\\s-+Server\\s-+Comment$" "Regexp used as prompt in smbclient.") (defconst tramp-smb-errors @@ -71,8 +71,8 @@ '(; Connection error "Connection to \\S-+ failed" ; Samba - "ERRSRV" "ERRDOS" + "ERRSRV" "ERRbadfile" "ERRbadpw" "ERRfilexists" @@ -81,13 +81,16 @@ "ERRnosuchshare" ; Windows NT 4.0, Windows 5.0 (Windows 2000), Windows 5.1 (Windows XP) "NT_STATUS_ACCESS_DENIED" + "NT_STATUS_ACCOUNT_LOCKED_OUT" "NT_STATUS_BAD_NETWORK_NAME" "NT_STATUS_CANNOT_DELETE" "NT_STATUS_LOGON_FAILURE" + "NT_STATUS_NETWORK_ACCESS_DENIED" "NT_STATUS_NO_SUCH_FILE" "NT_STATUS_OBJECT_NAME_INVALID" "NT_STATUS_OBJECT_NAME_NOT_FOUND" - "NT_STATUS_SHARING_VIOLATION") + "NT_STATUS_SHARING_VIOLATION" + "NT_STATUS_WRONG_PASSWORD") "\\|") "Regexp for possible error strings of SMB servers. Used instead of analyzing error codes of commands.") @@ -102,12 +105,6 @@ This variable is local to each buffer.") This variable is local to each buffer.") (make-variable-buffer-local 'tramp-smb-share-cache) -(defvar tramp-smb-process-running nil - "Flag whether a corresponding process is still running. -Will be changed by corresponding `process-sentinel'. -This variable is local to each buffer.") -(make-variable-buffer-local 'tramp-smb-process-running) - (defvar tramp-smb-inodes nil "Keeps virtual inodes numbers for SMB files.") @@ -290,7 +287,7 @@ KEEP-DATE is not handled in case NEWNAME resides on an SMB server." (tramp-smb-send-command user host (format "cd \\")) ;; Error (tramp-smb-send-command user host (format "cd \\")) - (error "Cannot delete file `%s'" directory)))))) + (error "Cannot delete file `%s'" filename)))))) (defun tramp-smb-handle-directory-files (directory &optional full match nosort) @@ -324,18 +321,18 @@ KEEP-DATE is not handled in case NEWNAME resides on an SMB server." entries)))) (defun tramp-smb-handle-directory-files-and-attributes - (directory &optional full match nosort) + (directory &optional full match nosort id-format) "Like `directory-files-and-attributes' for tramp files." (mapcar (lambda (x) - (cons x (file-attributes - (if full x (concat (file-name-as-directory directory) x))))) + ;; We cannot call `file-attributes' for backward compatibility reasons. + ;; Its optional parameter ID-FORMAT is introduced with Emacs 21.4. + (cons x (tramp-smb-handle-file-attributes + (if full x (concat (file-name-as-directory directory) x)) id-format))) (directory-files directory full match nosort))) -(defun tramp-smb-handle-file-attributes (filename &optional nonnumeric) - "Like `file-attributes' for tramp files. -Optional argument NONNUMERIC means return user and group name -rather than as numbers." +(defun tramp-smb-handle-file-attributes (filename &optional id-format) + "Like `file-attributes' for tramp files." ; (with-parsed-tramp-file-name filename nil (let (user host localname) (with-parsed-tramp-file-name filename l @@ -346,6 +343,8 @@ rather than as numbers." (entries (tramp-smb-get-file-entries user host share file)) (entry (and entries (assoc (file-name-nondirectory file) entries))) + (uid (if (and id-format (equal id-format 'string)) "nobody" -1)) + (gid (if (and id-format (equal id-format 'string)) "nogroup" -1)) (inode (tramp-smb-get-inode share file)) (device (tramp-get-device nil tramp-smb-method user host))) @@ -354,8 +353,8 @@ rather than as numbers." (list (and (string-match "d" (nth 1 entry)) t) ;0 file type -1 ;1 link count - -1 ;2 uid - -1 ;3 gid + uid ;2 uid + gid ;3 gid '(0 0) ;4 atime (nth 3 entry) ;5 mtime '(0 0) ;6 ctime @@ -450,19 +449,23 @@ rather than as numbers." (defun tramp-smb-handle-file-writable-p (filename) "Like `file-writable-p' for tramp files." -; (with-parsed-tramp-file-name filename nil - (let (user host localname) - (with-parsed-tramp-file-name filename l - (setq user l-user host l-host localname l-localname)) - (save-excursion - (let* ((share (tramp-smb-get-share localname)) - (file (tramp-smb-get-localname localname nil)) - (entries (tramp-smb-get-file-entries user host share file)) - (entry (and entries - (assoc (file-name-nondirectory file) entries)))) - (and entry - (string-match "w" (nth 1 entry)) - t))))) + (if (not (file-exists-p filename)) + (let ((dir (file-name-directory filename))) + (and (file-exists-p dir) + (file-writable-p dir))) +; (with-parsed-tramp-file-name filename nil + (let (user host localname) + (with-parsed-tramp-file-name filename l + (setq user l-user host l-host localname l-localname)) + (save-excursion + (let* ((share (tramp-smb-get-share localname)) + (file (tramp-smb-get-localname localname nil)) + (entries (tramp-smb-get-file-entries user host share file)) + (entry (and entries + (assoc (file-name-nondirectory file) entries)))) + (and share entry + (string-match "w" (nth 1 entry)) + t)))))) (defun tramp-smb-handle-insert-directory (filename switches &optional wildcard full-directory-p) @@ -546,7 +549,7 @@ WILDCARD and FULL-DIRECTORY-P are not handled." "Like `make-directory-internal' for tramp files." (setq directory (directory-file-name (expand-file-name directory))) (unless (file-name-absolute-p directory) - (setq ldir (concat default-directory directory))) + (setq directory (concat default-directory directory))) ; (with-parsed-tramp-file-name directory nil (let (user host localname) (with-parsed-tramp-file-name directory l @@ -731,9 +734,12 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)." ;; Cache share entries (setq tramp-smb-share-cache res))) - ;; Add directory itself - (add-to-list 'res '("" "dr-xr-xr-x" 0 (0 0))) + (add-to-list 'res '("" "drwxrwxrwx" 0 (0 0))) + + ;; There's a very strange error (debugged with XEmacs 21.4.14) + ;; If there's no short delay, it returns nil. No idea about + (when (featurep 'xemacs) (sleep-for 0.01)) ;; Check for matching entries (delq nil (mapcar @@ -911,7 +917,8 @@ there has been an error message from smbclient." "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'. Does not do anything if a connection is already open, but re-opens the connection if a previous connection has died for some reason." - (let ((p (get-buffer-process + (let ((process-connection-type tramp-process-connection-type) + (p (get-buffer-process (tramp-get-buffer nil tramp-smb-method user host)))) (save-excursion (set-buffer (tramp-get-buffer nil tramp-smb-method user host)) @@ -985,11 +992,7 @@ Domain names in USER and port numbers in HOST are acknowledged." (tramp-message 9 "Started process %s" (process-command p)) (process-kill-without-query p) (set-buffer buffer) - (set-process-sentinel - p (lambda (proc str) (setq tramp-smb-process-running nil))) - ; If no share is given, the process will terminate - (setq tramp-smb-process-running share - tramp-smb-share share) + (setq tramp-smb-share share) ; send password (when real-user @@ -998,54 +1001,44 @@ Domain names in USER and port numbers in HOST are acknowledged." (tramp-enter-password p pw-prompt))) (unless (tramp-smb-wait-for-output user host) + (tramp-clear-passwd user host) (error "Cannot open connection //%s@%s/%s" user host (or share ""))))))) ;; We don't use timeouts. If needed, the caller shall wrap around. (defun tramp-smb-wait-for-output (user host) "Wait for output from smbclient command. -Sets position to begin of buffer. Returns nil if an error message has appeared." - (save-excursion - (let ((proc (get-buffer-process (current-buffer))) - (found (progn (goto-char (point-max)) - (beginning-of-line) - (looking-at tramp-smb-prompt))) - err) - (save-match-data - ;; Algorithm: get waiting output. See if last line contains - ;; tramp-smb-prompt sentinel, or process has exited. - ;; If not, wait a bit and again get waiting output. - (while (and (not found) tramp-smb-process-running) - (accept-process-output proc) - (goto-char (point-max)) - (beginning-of-line) - (setq found (looking-at tramp-smb-prompt))) - - ;; There might be pending output. If tramp-smb-prompt sentinel - ;; hasn't been found, the process has died already. We should - ;; give it a chance. - (when (not found) (accept-process-output nil 1)) - - ;; Search for errors. - (goto-char (point-min)) - (setq err (re-search-forward tramp-smb-errors nil t))) - - ;; Add output to debug buffer if appropriate. - (when tramp-debug-buffer - (append-to-buffer - (tramp-get-debug-buffer nil tramp-smb-method user host) - (point-min) (point-max)) - (when (and (not found) tramp-smb-process-running) - (save-excursion - (set-buffer - (tramp-get-debug-buffer nil tramp-smb-method user host)) - (goto-char (point-max)) - (insert (format "[[Remote prompt `%s' not found]]\n" - tramp-smb-prompt))))) + (let ((proc (get-buffer-process (current-buffer))) + (found (progn (goto-char (point-min)) + (re-search-forward tramp-smb-prompt nil t))) + (err (progn (goto-char (point-min)) + (re-search-forward tramp-smb-errors nil t)))) + + ;; Algorithm: get waiting output. See if last line contains + ;; tramp-smb-prompt sentinel or tramp-smb-errors strings. + ;; If not, wait a bit and again get waiting output. + (while (and (not found) (not err)) + + ;; Accept pending output. + (accept-process-output proc) + + ;; Search for prompt. (goto-char (point-min)) - ;; Return value is whether no error message has appeared. - (not err)))) + (setq found (re-search-forward tramp-smb-prompt nil t)) + + ;; Search for errors. + (goto-char (point-min)) + (setq err (re-search-forward tramp-smb-errors nil t))) + + ;; Add output to debug buffer if appropriate. + (when tramp-debug-buffer + (append-to-buffer + (tramp-get-debug-buffer nil tramp-smb-method user host) + (point-min) (point-max))) + + ;; Return value is whether no error message has appeared. + (not err))) ;; Snarfed code from time-date.el and parse-time.el @@ -1123,8 +1116,6 @@ Return the difference in the format of a time value." ;; * Provide a local smb.conf. The default one might not be readable. ;; * Error handling in case password is wrong. ;; * Read password from "~/.netrc". -;; * Use different buffers for different shares. By this, the password -;; won't be requested again when changing shares on the same host. ;; * Return more comprehensive file permission string. Think whether it is ;; possible to implement `set-file-modes'. ;; * Handle WILDCARD and FULL-DIRECTORY-P in @@ -1139,4 +1130,5 @@ Return the difference in the format of a time value." ;; * (RMS) Use unwind-protect to clean up the state so as to make the state ;; regular again. +;;; arch-tag: fcc9dbec-7503-4d73-b638-3c8aa59575f5 ;;; tramp-smb.el ends here diff --git a/lisp/net/tramp-util.el b/lisp/net/tramp-util.el index 44a24ca3ab7..2d828d27c51 100644 --- a/lisp/net/tramp-util.el +++ b/lisp/net/tramp-util.el @@ -52,4 +52,6 @@ (compilation-minor-mode 1)) (provide 'tramp-util) + +;;; arch-tag: 500f9992-a44e-46d0-83a7-980799251808 ;;; tramp-util.el ends here diff --git a/lisp/net/tramp-uu.el b/lisp/net/tramp-uu.el index e307febc6fc..1047e62a3cb 100644 --- a/lisp/net/tramp-uu.el +++ b/lisp/net/tramp-uu.el @@ -87,4 +87,6 @@ (insert "begin 600 xxx\n")))) (provide 'tramp-uu) + +;;; arch-tag: 7153f2c6-8be5-4cd2-8c06-0fbcf5190ef6 ;;; tramp-uu.el ends here diff --git a/lisp/net/tramp-vc.el b/lisp/net/tramp-vc.el index cee13308d38..ded30f4b09c 100644 --- a/lisp/net/tramp-vc.el +++ b/lisp/net/tramp-vc.el @@ -391,8 +391,15 @@ filename we are thinking about..." ;; Pacify byte-compiler; this symbol is bound in the calling ;; function. CCC: Maybe it would be better to move the ;; boundness-checking into this function? - (let ((file (symbol-value 'file))) - (if (and uid (/= uid (nth 2 (file-attributes file)))) + (let ((file (symbol-value 'file)) + (remote-uid + ;; With Emacs 21.4, `file-attributes' has got an optional parameter + ;; ID-FORMAT. Handle this case backwards compatible. + (if (and (functionp 'subr-arity) + (= 2 (cdr (subr-arity (symbol-function 'file-attributes))))) + (nth 2 (file-attributes file 'integer)) + (nth 2 (file-attributes file))))) + (if (and uid (/= uid remote-uid)) (error "tramp-handle-vc-user-login-name cannot map a uid to a name") (let* ((v (tramp-dissect-file-name (tramp-handle-expand-file-name file))) (u (tramp-file-name-user v))) @@ -486,4 +493,5 @@ This makes remote VC work correctly at the cost of some processing time." ;; No need to load this again if anyone asks. (provide 'tramp-vc) +;;; arch-tag: 27cc42ce-da19-468d-ad5c-a2690558db60 ;;; tramp-vc.el ends here diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 966d93b719c..cd6ed337927 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1,7 +1,7 @@ ;;; -*- mode: Emacs-Lisp; coding: iso-2022-7bit; -*- ;;; tramp.el --- Transparent Remote Access, Multiple Protocol -;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: kai.grossjohann@gmx.net ;; Keywords: comm, processes @@ -72,6 +72,12 @@ (require 'timer) (require 'format-spec) ;from Gnus 5.8, also in tar ball +;; As long as password.el is not part of (X)Emacs, it shouldn't +;; be mandatory +(if (featurep 'xemacs) + (load "password" 'noerror) + (require 'password nil 'noerror)) ;from No Gnus, also in tar ball + ;; The explicit check is not necessary in Emacs, which provides the ;; feature even if implemented in C, but it appears to be necessary ;; in XEmacs. @@ -569,6 +575,7 @@ variable `tramp-methods'." ("rsh" tramp-multi-connect-rlogin "rsh %h -l %u%n") ("remsh" tramp-multi-connect-rlogin "remsh %h -l %u%n") ("ssh" tramp-multi-connect-rlogin "ssh %h -l %u%n") + ("ssht" tramp-multi-connect-rlogin "ssh %h -e none -t -t -l %u%n") ("su" tramp-multi-connect-su "su - %u%n") ("sudo" tramp-multi-connect-su "sudo -u %u -s -p Password:%n")) "*List of connection functions for multi-hop methods. @@ -627,14 +634,18 @@ See `tramp-methods' for a list of possibilities for METHOD." ;; Default values for non-Unices seeked (defconst tramp-completion-function-alist-ssh (unless (memq system-type '(windows-nt)) - '((tramp-parse-rhosts "/etc/hosts.equiv") - (tramp-parse-rhosts "/etc/shosts.equiv") - (tramp-parse-shosts "/etc/ssh_known_hosts") - (tramp-parse-sconfig "/etc/ssh_config") - (tramp-parse-rhosts "~/.rhosts") - (tramp-parse-rhosts "~/.shosts") - (tramp-parse-shosts "~/.ssh/known_hosts") - (tramp-parse-sconfig "~/.ssh/config"))) + '((tramp-parse-rhosts "/etc/hosts.equiv") + (tramp-parse-rhosts "/etc/shosts.equiv") + (tramp-parse-shosts "/etc/ssh_known_hosts") + (tramp-parse-sconfig "/etc/ssh_config") + (tramp-parse-shostkeys "/etc/ssh2/hostkeys") + (tramp-parse-sknownhosts "/etc/ssh2/knownhosts") + (tramp-parse-rhosts "~/.rhosts") + (tramp-parse-rhosts "~/.shosts") + (tramp-parse-shosts "~/.ssh/known_hosts") + (tramp-parse-sconfig "~/.ssh/config") + (tramp-parse-shostkeys "~/.ssh2/hostkeys") + (tramp-parse-sknownhosts "~/.ssh2/knownhosts"))) "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.") ;; Default values for non-Unices seeked @@ -649,53 +660,79 @@ See `tramp-methods' for a list of possibilities for METHOD." '((tramp-parse-passwd "/etc/passwd"))) "Default list of (FUNCTION FILE) pairs to be examined for su methods.") -(defcustom tramp-completion-function-alist - (list (cons "rcp" tramp-completion-function-alist-rsh) - (cons "scp" tramp-completion-function-alist-ssh) - (cons "scp1" tramp-completion-function-alist-ssh) - (cons "scp2" tramp-completion-function-alist-ssh) - (cons "scp1_old" tramp-completion-function-alist-ssh) - (cons "scp2_old" tramp-completion-function-alist-ssh) - (cons "rsync" tramp-completion-function-alist-rsh) - (cons "remcp" tramp-completion-function-alist-rsh) - (cons "rsh" tramp-completion-function-alist-rsh) - (cons "ssh" tramp-completion-function-alist-ssh) - (cons "ssh1" tramp-completion-function-alist-ssh) - (cons "ssh2" tramp-completion-function-alist-ssh) - (cons "ssh1_old" tramp-completion-function-alist-ssh) - (cons "ssh2_old" tramp-completion-function-alist-ssh) - (cons "remsh" tramp-completion-function-alist-rsh) - (cons "telnet" tramp-completion-function-alist-telnet) - (cons "su" tramp-completion-function-alist-su) - (cons "sudo" tramp-completion-function-alist-su) - (cons "multi" nil) - (cons "scpx" tramp-completion-function-alist-ssh) - (cons "sshx" tramp-completion-function-alist-ssh) - (cons "krlogin" tramp-completion-function-alist-rsh) - (cons "plink" tramp-completion-function-alist-ssh) - (cons "plink1" tramp-completion-function-alist-ssh) - (cons "pscp" tramp-completion-function-alist-ssh) - (cons "fcp" tramp-completion-function-alist-ssh) - ) +(defvar tramp-completion-function-alist nil "*Alist of methods for remote files. This is a list of entries of the form (NAME PAIR1 PAIR2 ...). Each NAME stands for a remote access method. Each PAIR is of the form \(FUNCTION FILE). FUNCTION is responsible to extract user names and host names from FILE for completion. The following predefined FUNCTIONs exists: - * `tramp-parse-rhosts' for \"~/.rhosts\" like files, - * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files, - * `tramp-parse-sconfig' for \"~/.ssh/config\" like files, - * `tramp-parse-hosts' for \"/etc/hosts\" like files, and - * `tramp-parse-passwd' for \"/etc/passwd\" like files. - * `tramp-parse-netrc' for \"~/.netrc\" like files. - -FUNCTION can also see a customer defined function. For more details see -the info pages." - :group 'tramp - :type '(repeat - (cons string - (choice (const nil) (repeat (list function file)))))) + * `tramp-parse-rhosts' for \"~/.rhosts\" like files, + * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files, + * `tramp-parse-sconfig' for \"~/.ssh/config\" like files, + * `tramp-parse-shostkeys' for \"~/.ssh2/hostkeys/*\" like files, + * `tramp-parse-sknownhosts' for \"~/.ssh2/knownhosts/*\" like files, + * `tramp-parse-hosts' for \"/etc/hosts\" like files, + * `tramp-parse-passwd' for \"/etc/passwd\" like files. + * `tramp-parse-netrc' for \"~/.netrc\" like files. + +FUNCTION can also be a customer defined function. For more details see +the info pages.") + +(eval-after-load "tramp" + '(progn + (tramp-set-completion-function + "rcp" tramp-completion-function-alist-rsh) + (tramp-set-completion-function + "scp" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "scp1" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "scp2" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "scp1_old" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "scp2_old" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "rsync" tramp-completion-function-alist-rsh) + (tramp-set-completion-function + "remcp" tramp-completion-function-alist-rsh) + (tramp-set-completion-function + "rsh" tramp-completion-function-alist-rsh) + (tramp-set-completion-function + "ssh" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "ssh1" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "ssh2" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "ssh1_old" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "ssh2_old" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "remsh" tramp-completion-function-alist-rsh) + (tramp-set-completion-function + "telnet" tramp-completion-function-alist-telnet) + (tramp-set-completion-function + "su" tramp-completion-function-alist-su) + (tramp-set-completion-function + "sudo" tramp-completion-function-alist-su) + (tramp-set-completion-function + "multi" nil) + (tramp-set-completion-function + "scpx" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "sshx" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "krlogin" tramp-completion-function-alist-rsh) + (tramp-set-completion-function + "plink" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "plink1" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "pscp" tramp-completion-function-alist-ssh) + (tramp-set-completion-function + "fcp" tramp-completion-function-alist-ssh))) (defcustom tramp-rsh-end-of-line "\n" "*String used for end of line in rsh connections. @@ -1250,11 +1287,33 @@ checked via the following code: (re-search-forward \"\\\\w+\") (message \"Bytes sent: %s\\tBytes received: %s\" bytes (match-string 0)))) +In the Emacs normally running Tramp, evaluate the above code. +You can do this, for example, by pasting it into the `*scratch*' +buffer and then hitting C-j with the cursor after the last +closing parenthesis. + +If your Emacs is buggy, the sent and received numbers will be +different. In that case, you'll want to set this variable to +some number. For those people who have needed it, the value 500 +seems to have worked well. There is no way to predict what value +you need; maybe you could just experiment a bit. + Please raise a bug report via \"M-x tramp-bug\" if your system needs this variable to be set as well." :group 'tramp :type '(choice (const nil) integer)) +;; Logging in to a remote host normally requires obtaining a pty. But +;; Emacs on MacOS X has process-connection-type set to nil by default, +;; so on those systems Tramp doesn't obtain a pty. Here, we allow +;; for an override of the system default. +(defcustom tramp-process-connection-type t + "Overrides `process-connection-type' for connections from Tramp. +Tramp binds process-connection-type to the value given here before +opening a connection to a remote host." + :group 'tramp + :type '(choice (const nil) (const t) (const pty))) + ;;; Internal Variables: (defvar tramp-buffer-file-attributes nil @@ -1405,13 +1464,15 @@ some systems don't, and for them we have this shell function.") ;; The device number is returned as "-1", because there will be a virtual ;; device number set in `tramp-handle-file-attributes' (defconst tramp-perl-file-attributes "\ -$f = $ARGV[0]; +($f, $n) = @ARGV; @s = lstat($f); if (($s[2] & 0170000) == 0120000) { $l = readlink($f); $l = \"\\\"$l\\\"\"; } elsif (($s[2] & 0170000) == 040000) { $l = \"t\"; } else { $l = \"nil\" }; -printf(\"(%s %u %d %d (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) -1)\\n\", -$l, $s[3], $s[4], $s[5], $s[8] >> 16 & 0xffff, $s[8] & 0xffff, +$u = ($n eq \"nil\") ? $s[4] : getpwuid($s[4]); +$g = ($n eq \"nil\") ? $s[5] : getgrgid($s[5]); +printf(\"(%s %u %s %s (%u %u) (%u %u) (%u %u) %u %u t (%u . %u) -1)\\n\", +$l, $s[3], $u, $g, $s[8] >> 16 & 0xffff, $s[8] & 0xffff, $s[9] >> 16 & 0xffff, $s[9] & 0xffff, $s[10] >> 16 & 0xffff, $s[10] & 0xffff, $s[7], $s[2], $s[1] >> 16 & 0xffff, $s[1] & 0xffff);" "Perl script to produce output suitable for use with `file-attributes' @@ -1624,6 +1685,7 @@ on the FILENAME argument, even if VISIT was a string.") (insert-file-contents . tramp-handle-insert-file-contents) (write-region . tramp-handle-write-region) (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) + (dired-compress-file . tramp-handle-dired-compress-file) (dired-call-process . tramp-handle-dired-call-process) (dired-recursive-delete-directory . tramp-handle-dired-recursive-delete-directory) @@ -1747,15 +1809,30 @@ Example: '((tramp-parse-sconfig \"/etc/ssh_config\") (tramp-parse-sconfig \"~/.ssh/config\")))" - (let ((v (cdr (assoc method tramp-completion-function-alist)))) - (if v (setcdr v function-list) + (let ((r function-list) + (v function-list)) + (setq tramp-completion-function-alist + (delete (assoc method tramp-completion-function-alist) + tramp-completion-function-alist)) + + (while v + ;; Remove double entries + (when (member (car v) (cdr v)) + (setcdr v (delete (car v) (cdr v)))) + ;; Check for function and file + (unless (and (functionp (nth 0 (car v))) + (file-exists-p (nth 1 (car v)))) + (setq r (delete (car v) r))) + (setq v (cdr v))) + + (when r (add-to-list 'tramp-completion-function-alist - (cons method function-list))))) + (cons method r))))) (defun tramp-get-completion-function (method) "Returns list of completion functions for METHOD. For definition of that list see `tramp-set-completion-function'." - (cdr (assoc method tramp-completion-function-alist))) + (cdr (assoc method tramp-completion-function-alist))) ;;; File Name Handler Functions: @@ -1900,7 +1977,7 @@ target of the symlink differ." (append '("") (reverse result) (list thisstep)) "/")) (setq symlink-target - (nth 0 (tramp-handle-file-attributes + (nth 0 (file-attributes (tramp-make-tramp-file-name multi-method method user host (mapconcat 'identity @@ -1979,11 +2056,10 @@ target of the symlink differ." ;; CCC: This should check for an error condition and signal failure ;; when something goes wrong. ;; Daniel Pittman <daniel@danann.net> -(defun tramp-handle-file-attributes (filename &optional nonnumeric) - "Like `file-attributes' for tramp files. -Optional argument NONNUMERIC means return user and group name -rather than as numbers." - (let (result) +(defun tramp-handle-file-attributes (filename &optional id-format) + "Like `file-attributes' for tramp files." + (let ((nonnumeric (and id-format (equal id-format 'string))) + result) (with-parsed-tramp-file-name filename nil (when (tramp-handle-file-exists-p filename) ;; file exists, find out stuff @@ -2097,8 +2173,8 @@ is initially created and is kept cached by the remote shell." multi-method method user host localname)) (tramp-send-command multi-method method user host - (format "tramp_file_attributes %s" - (tramp-shell-quote-argument localname))) + (format "tramp_file_attributes %s %s" + (tramp-shell-quote-argument localname) nonnumeric)) (tramp-wait-for-output) (let ((result (read (current-buffer)))) (setcar (nthcdr 8 result) @@ -2310,7 +2386,7 @@ if the remote host can't provide the modtime." (defun tramp-handle-file-symlink-p (filename) "Like `file-symlink-p' for tramp files." (with-parsed-tramp-file-name filename nil - (let ((x (car (tramp-handle-file-attributes filename)))) + (let ((x (car (file-attributes filename)))) (when (stringp x) ;; When Tramp is running on VMS, then `file-name-absolute-p' ;; might do weird things. @@ -2573,44 +2649,86 @@ and `rename'. FILENAME and NEWNAME must be absolute file names." (signal 'file-already-exists (list newname)))) (let ((t1 (tramp-tramp-file-p filename)) - (t2 (tramp-tramp-file-p newname))) + (t2 (tramp-tramp-file-p newname)) + v1-multi-method v1-method v1-user v1-host v1-localname + v2-multi-method v2-method v2-user v2-host v2-localname) + ;; Check which ones of source and target are Tramp files. + ;; We cannot invoke `with-parsed-tramp-file-name'; + ;; it fails if the file isn't a Tramp file name. + (if t1 + (with-parsed-tramp-file-name filename l + (setq v1-multi-method l-multi-method + v1-method l-method + v1-user l-user + v1-host l-host + v1-localname l-localname)) + (setq v1-localname filename)) + (if t2 + (with-parsed-tramp-file-name newname l + (setq v2-multi-method l-multi-method + v2-method l-method + v2-user l-user + v2-host l-host + v2-localname l-localname)) + (setq v2-localname newname)) + (cond + ;; Both are Tramp files. ((and t1 t2) - ;; Both are Tramp files. - (with-parsed-tramp-file-name filename v1 - (with-parsed-tramp-file-name newname v2 - ;; Check if we can use a shortcut. - (if (and (equal v1-multi-method v2-multi-method) - (equal v1-method v2-method) - (equal v1-host v2-host) - (equal v1-user v2-user)) - ;; Shortcut: if method, host, user are the same for both - ;; files, we invoke `cp' or `mv' on the remote host - ;; directly. - (tramp-do-copy-or-rename-file-directly - op v1-multi-method v1-method v1-user v1-host - v1-localname v2-localname keep-date) - ;; The shortcut was not possible. So we copy the - ;; file first. If the operation was `rename', we go - ;; back and delete the original file (if the copy was - ;; successful). The approach is simple-minded: we - ;; create a new buffer, insert the contents of the - ;; source file into it, then write out the buffer to - ;; the target file. The advantage is that it doesn't - ;; matter which filename handlers are used for the - ;; source and target file. - - ;; CCC: If both source and target are Tramp files, - ;; and both are using the same copy-program, then we - ;; can invoke rcp directly. Note that - ;; default-directory should point to a local - ;; directory if we want to invoke rcp. - (tramp-do-copy-or-rename-via-buffer - op filename newname keep-date))))) + (cond + ;; Shortcut: if method, host, user are the same for both + ;; files, we invoke `cp' or `mv' on the remote host + ;; directly. + ((and (equal v1-multi-method v2-multi-method) + (equal v1-method v2-method) + (equal v1-user v2-user) + (equal v1-host v2-host)) + (tramp-do-copy-or-rename-file-directly + op v1-multi-method v1-method v1-user v1-host + v1-localname v2-localname keep-date)) + ;; If both source and target are Tramp files, + ;; both are using the same copy-program, then we + ;; can invoke rcp directly. Note that + ;; default-directory should point to a local + ;; directory if we want to invoke rcp. + ((and (not v1-multi-method) + (not v2-multi-method) + (equal v1-method v2-method) + (tramp-method-out-of-band-p + v1-multi-method v1-method v1-user v1-host) + (not (string-match "\\([^#]*\\)#\\(.*\\)" v1-host)) + (not (string-match "\\([^#]*\\)#\\(.*\\)" v2-host))) + (tramp-do-copy-or-rename-file-out-of-band + op filename newname keep-date)) + ;; No shortcut was possible. So we copy the + ;; file first. If the operation was `rename', we go + ;; back and delete the original file (if the copy was + ;; successful). The approach is simple-minded: we + ;; create a new buffer, insert the contents of the + ;; source file into it, then write out the buffer to + ;; the target file. The advantage is that it doesn't + ;; matter which filename handlers are used for the + ;; source and target file. + (t + (tramp-do-copy-or-rename-via-buffer + op filename newname keep-date)))) + + ;; One file is a Tramp file, the other one is local. ((or t1 t2) - ;; Use the generic method via a Tramp buffer. - (tramp-do-copy-or-rename-via-buffer op filename newname keep-date)) + ;; If the Tramp file has an out-of-band method, the corresponding + ;; copy-program can be invoked. + (if (and (not v1-multi-method) + (not v2-multi-method) + (or (tramp-method-out-of-band-p + v1-multi-method v1-method v1-user v1-host) + (tramp-method-out-of-band-p + v2-multi-method v2-method v2-user v2-host))) + (tramp-do-copy-or-rename-file-out-of-band + op filename newname keep-date) + ;; Use the generic method via a Tramp buffer. + (tramp-do-copy-or-rename-via-buffer op filename newname keep-date))) + (t ;; One of them must be a Tramp file. (error "Tramp implementation says this cannot happen"))))) @@ -2621,8 +2739,9 @@ and `rename'. FILENAME and NEWNAME must be absolute file names." First arg OP is either `copy' or `rename' and indicates the operation. FILENAME is the source file, NEWNAME the target file. KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." - (let ((trampbuf (get-buffer-create "*tramp output*"))) - (when keep-date + (let ((trampbuf (get-buffer-create "*tramp output*")) + (modtime (nth 5 (file-attributes filename)))) + (when (and keep-date (or (null modtime) (equal modtime '(0 0)))) (tramp-message 1 (concat "Warning: cannot preserve file time stamp" " with inline copying across machines"))) @@ -2633,7 +2752,12 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." ;; `jka-compr-inhibit' to t. (let ((coding-system-for-write 'binary) (jka-compr-inhibit t)) - (write-region (point-min) (point-max) newname))) + (write-region (point-min) (point-max) newname)) + ;; KEEP-DATE handling. + (when (and keep-date + (not (null modtime)) + (not (equal modtime '(0 0)))) + (tramp-touch newname modtime))) ;; If the operation was `rename', delete the original file. (unless (eq op 'copy) (delete-file filename)))) @@ -2663,13 +2787,112 @@ If KEEP-DATE is non-nil, preserve the time stamp when copying." "Copying directly failed, see buffer `%s' for details." (buffer-name))))) -(defun tramp-do-copy-or-rename-file-one-local - (op filename newname keep-date) +(defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date) "Invoke rcp program to copy. One of FILENAME and NEWNAME must be a Tramp name, the other must be a local filename. The method used must be an out-of-band method." - ;; CCC - ) + (let ((trampbuf (get-buffer-create "*tramp output*")) + (t1 (tramp-tramp-file-p filename)) + (t2 (tramp-tramp-file-p newname)) + v1-multi-method v1-method v1-user v1-host v1-localname + v2-multi-method v2-method v2-user v2-host v2-localname + method copy-program copy-args source target) + + ;; Check which ones of source and target are Tramp files. + ;; We cannot invoke `with-parsed-tramp-file-name'; + ;; it fails if the file isn't a Tramp file name. + (if t1 + (with-parsed-tramp-file-name filename l + (setq v1-multi-method l-multi-method + v1-method l-method + v1-user l-user + v1-host l-host + v1-localname l-localname + method (tramp-find-method + v1-multi-method v1-method v1-user v1-host) + copy-program (tramp-get-method-parameter + v1-multi-method method + v1-user v1-host 'tramp-copy-program) + copy-args (tramp-get-method-parameter + v1-multi-method method + v1-user v1-host 'tramp-copy-args))) + (setq v1-localname filename)) + + (if t2 + (with-parsed-tramp-file-name newname l + (setq v2-multi-method l-multi-method + v2-method l-method + v2-user l-user + v2-host l-host + v2-localname l-localname + method (tramp-find-method + v2-multi-method v2-method v2-user v2-host) + copy-program (tramp-get-method-parameter + v2-multi-method method + v2-user v2-host 'tramp-copy-program) + copy-args (tramp-get-method-parameter + v2-multi-method method + v2-user v2-host 'tramp-copy-args))) + (setq v2-localname newname)) + + ;; The following should be changed. We need a more general + ;; mechanism to parse extra host args. + (if (not t1) + (setq source v1-localname) + (when (string-match "\\([^#]*\\)#\\(.*\\)" v1-host) + (setq copy-args (cons "-P" (cons (match-string 2 v1-host) copy-args))) + (setq v1-host (match-string 1 v1-host))) + (setq source + (tramp-make-copy-program-file-name + v1-user v1-host + (tramp-shell-quote-argument v1-localname)))) + + (if (not t2) + (setq target v2-localname) + (when (string-match "\\([^#]*\\)#\\(.*\\)" v2-host) + (setq copy-args (cons "-P" (cons (match-string 2 v2-host) copy-args))) + (setq v2-host (match-string 1 v2-host))) + (setq target + (tramp-make-copy-program-file-name + v2-user v2-host + (tramp-shell-quote-argument v2-localname)))) + + ;; Handle keep-date argument + (when keep-date + (if t1 + (setq copy-args + (cons (tramp-get-method-parameter + v1-multi-method method + v1-user v1-host 'tramp-copy-keep-date-arg) + copy-args)) + (setq copy-args + (cons (tramp-get-method-parameter + v2-multi-method method + v2-user v2-host 'tramp-copy-keep-date-arg) + copy-args)))) + + (setq copy-args (append copy-args (list source target))) + + ;; Use rcp-like program for file transfer. + (tramp-message + 5 "Transferring %s to file %s..." filename newname) + (save-excursion (set-buffer trampbuf) (erase-buffer)) + (unless (equal + 0 + (apply #'call-process copy-program + nil trampbuf nil copy-args)) + (pop-to-buffer trampbuf) + (error + (concat + "tramp-do-copy-or-rename-file-out-of-band: `%s' didn't work, " + "see buffer `%s' for details") + copy-program trampbuf)) + (tramp-message + 5 "Transferring %s to file %s...done" filename newname) + + ;; If the operation was `rename', delete the original file. + (unless (eq op 'copy) + (delete-file filename)))) ;; mkdir (defun tramp-handle-make-directory (dir &optional parents) @@ -2732,7 +2955,6 @@ This is like `dired-recursive-delete-directory' for tramp files." (and (tramp-handle-file-exists-p filename) (error "Failed to recusively delete %s" filename)))) - (defun tramp-handle-dired-call-process (program discard &rest arguments) "Like `dired-call-process' for tramp files." (with-parsed-tramp-file-name default-directory nil @@ -2754,6 +2976,59 @@ This is like `dired-recursive-delete-directory' for tramp files." (tramp-send-command-and-check multi-method method user host nil) (tramp-send-command multi-method method user host "cd") (tramp-wait-for-output))))) + +(defun tramp-handle-dired-compress-file (file &rest ok-flag) + "Like `dired-compress-file' for tramp files." + ;; OK-FLAG is valid for XEmacs only, but not implemented. + ;; Code stolen mainly from dired-aux.el. + (with-parsed-tramp-file-name file nil + (save-excursion + (let ((suffixes + (if (not (featurep 'xemacs)) + ;; Emacs case + (symbol-value 'dired-compress-file-suffixes) + ;; XEmacs has `dired-compression-method-alist', which is + ;; transformed into `dired-compress-file-suffixes' structure. + (mapcar + '(lambda (x) + (list (concat (regexp-quote (nth 1 x)) "\\'") + nil + (mapconcat 'identity (nth 3 x) " "))) + (symbol-value 'dired-compression-method-alist)))) + suffix) + ;; See if any suffix rule matches this file name. + (while suffixes + (let (case-fold-search) + (if (string-match (car (car suffixes)) localname) + (setq suffix (car suffixes) suffixes nil)) + (setq suffixes (cdr suffixes)))) + + (cond ((file-symlink-p file) + nil) + ((and suffix (nth 2 suffix)) + ;; We found an uncompression rule. + (message "Uncompressing %s..." file) + (when (zerop (tramp-send-command-and-check + multi-method method user host + (concat (nth 2 suffix) " " localname))) + (message "Uncompressing %s...done" file) + (dired-remove-file file) + (string-match (car suffix) file) + (concat (substring file 0 (match-beginning 0))))) + (t + ;; We don't recognize the file as compressed, so compress it. + ;; Try gzip. + (message "Compressing %s..." file) + (when (zerop (tramp-send-command-and-check + multi-method method user host + (concat "gzip -f " localname))) + (message "Compressing %s...done" file) + (dired-remove-file file) + (cond ((file-exists-p (concat file ".gz")) + (concat file ".gz")) + ((file-exists-p (concat file ".z")) + (concat file ".z")) + (t nil))))))))) ;; Pacify byte-compiler. The function is needed on XEmacs only. I'm ;; not sure at all that this is the right way to do it, but let's hope @@ -2948,17 +3223,40 @@ the result will be a local, non-Tramp, filename." ;; Remote commands. +(defvar tramp-async-proc nil + "Global variable keeping asyncronous process object. +Used in `tramp-handle-shell-command'") + (defun tramp-handle-shell-command (command &optional output-buffer error-buffer) "Like `shell-command' for tramp files. This will break if COMMAND prints a newline, followed by the value of `tramp-end-of-output', followed by another newline." + ;; Asynchronous processes are far from being perfect. But it works at least + ;; for `find-grep-dired' and `find-name-dired' in Emacs 21.4. (if (tramp-tramp-file-p default-directory) (with-parsed-tramp-file-name default-directory nil - (let (status) - (when (string-match "&[ \t]*\\'" command) - (error "Tramp doesn't grok asynchronous shell commands, yet")) -;; (when error-buffer -;; (error "Tramp doesn't grok optional third arg ERROR-BUFFER, yet")) + (let ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) + status) + (unless output-buffer + (setq output-buffer + (get-buffer-create + (if asynchronous + "*Async Shell Command*" + "*Shell Command Output*"))) + (set-buffer output-buffer) + (erase-buffer)) + (unless (bufferp output-buffer) + (setq output-buffer (current-buffer))) + (set-buffer output-buffer) + ;; Tramp doesn't handle the asynchronous case by an asynchronous + ;; process. Instead of, another asynchronous process is opened + ;; which gets the output of the (synchronous) Tramp process + ;; via process-filter. ERROR-BUFFER is disabled. + (when asynchronous + (setq command (substring command 0 (match-beginning 0)) + error-buffer nil + tramp-async-proc (start-process (buffer-name output-buffer) + output-buffer "cat"))) (save-excursion (tramp-barf-unless-okay multi-method method user host @@ -2966,23 +3264,39 @@ This will break if COMMAND prints a newline, followed by the value of nil 'file-error "tramp-handle-shell-command: Couldn't `cd %s'" (tramp-shell-quote-argument localname)) + ;; Define the process filter + (when asynchronous + (set-process-filter + (get-buffer-process + (tramp-get-buffer multi-method method user host)) + '(lambda (process string) + ;; Write the output into the Tramp Process + (save-current-buffer + (set-buffer (process-buffer process)) + (goto-char (point-max)) + (insert string)) + ;; Hand-over output to asynchronous process. + (let ((end + (string-match + (regexp-quote tramp-end-of-output) string))) + (when end + (setq string + (substring string 0 (1- (match-beginning 0))))) + (process-send-string tramp-async-proc string) + (when end + (set-process-filter process nil) + (process-send-eof tramp-async-proc)))))) + ;; Send the command (tramp-send-command multi-method method user host (if error-buffer (format "( %s ) 2>/tmp/tramp.$$.err; tramp_old_status=$?" command) - (format "%s ;tramp_old_status=$?" command))) - ;; This will break if the shell command prints "/////" - ;; somewhere. Let's just hope for the best... - (tramp-wait-for-output)) - (unless output-buffer - (setq output-buffer (get-buffer-create "*Shell Command Output*")) - (set-buffer output-buffer) - (erase-buffer)) - (unless (bufferp output-buffer) - (setq output-buffer (current-buffer))) - (set-buffer output-buffer) - (insert-buffer (tramp-get-buffer multi-method method user host)) + (format "%s; tramp_old_status=$?" command))) + (unless asynchronous + (tramp-wait-for-output))) + (unless asynchronous + (insert-buffer (tramp-get-buffer multi-method method user host))) (when error-buffer (save-excursion (unless (bufferp error-buffer) @@ -2997,17 +3311,19 @@ This will break if COMMAND prints a newline, followed by the value of multi-method method user host "rm -f /tmp/tramp.$$.err"))) (save-excursion (tramp-send-command multi-method method user host "cd") - (tramp-wait-for-output) + (unless asynchronous + (tramp-wait-for-output)) (tramp-send-command multi-method method user host (concat "tramp_set_exit_status $tramp_old_status;" " echo tramp_exit_status $?")) - (tramp-wait-for-output) - (goto-char (point-max)) - (unless (search-backward "tramp_exit_status " nil t) - (error "Couldn't find exit status of `%s'" command)) - (skip-chars-forward "^ ") - (setq status (read (current-buffer)))) + (unless asynchronous + (tramp-wait-for-output) + (goto-char (point-max)) + (unless (search-backward "tramp_exit_status " nil t) + (error "Couldn't find exit status of `%s'" command)) + (skip-chars-forward "^ ") + (setq status (read (current-buffer))))) (unless (zerop (buffer-size)) (display-buffer output-buffer)) status)) @@ -3028,16 +3344,7 @@ This will break if COMMAND prints a newline, followed by the value of (defun tramp-handle-file-local-copy (filename) "Like `file-local-copy' for tramp files." (with-parsed-tramp-file-name filename nil - (let ((output-buf (get-buffer-create "*tramp output*")) - (tramp-buf (tramp-get-buffer multi-method method user host)) - (copy-program (tramp-get-copy-program - multi-method - (tramp-find-method multi-method method user host) - user host)) - (copy-args (tramp-get-copy-args - multi-method - (tramp-find-method multi-method method user host) - user host)) + (let ((tramp-buf (tramp-get-buffer multi-method method user host)) ;; We used to bind the following as late as possible. ;; loc-enc and loc-dec were bound directly before the if ;; statement that checks them. But the functions @@ -3053,37 +3360,12 @@ This will break if COMMAND prints a newline, followed by the value of (error "Cannot make local copy of non-existing file `%s'" filename)) (setq tmpfil (tramp-make-temp-file)) - (cond (copy-program - ;; The following should be changed. We need a more general - ;; mechanism to parse extra host args. - (when (string-match "\\([^#]*\\)#\\(.*\\)" host) - (setq copy-args (cons "-p" (cons (match-string 2 host) - rsh-args))) - (setq host (match-string 1 host))) - ;; Use rcp-like program for file transfer. - (tramp-message-for-buffer - multi-method method user host - 5 "Fetching %s to tmp file %s..." filename tmpfil) - (save-excursion (set-buffer output-buf) (erase-buffer)) - (unless (equal - 0 - (apply #'call-process - copy-program - nil output-buf nil - (append copy-args - (list - (tramp-make-copy-program-file-name - user host - (tramp-shell-quote-argument localname)) - tmpfil)))) - (pop-to-buffer output-buf) - (error - (concat "tramp-handle-file-local-copy: `%s' didn't work, " - "see buffer `%s' for details") - copy-program output-buf)) - (tramp-message-for-buffer - multi-method method user host - 5 "Fetching %s to tmp file %s...done" filename tmpfil)) + + + (cond ((tramp-method-out-of-band-p multi-method method user host) + ;; `copy-file' handles out-of-band methods + (copy-file filename tmpfil t t)) + ((and rem-enc rem-dec) ;; Use inline encoding for file transfer. (save-excursion @@ -3212,14 +3494,6 @@ This will break if COMMAND prints a newline, followed by the value of (error "File not overwritten"))) (with-parsed-tramp-file-name filename nil (let ((curbuf (current-buffer)) - (copy-program (tramp-get-copy-program - multi-method - (tramp-find-method multi-method method user host) - user host)) - (copy-args (tramp-get-copy-args - multi-method - (tramp-find-method multi-method method user host) - user host)) (rem-enc (tramp-get-remote-encoding multi-method method user host)) (rem-dec (tramp-get-remote-decoding multi-method method user host)) (loc-enc (tramp-get-local-encoding multi-method method user host)) @@ -3254,44 +3528,10 @@ This will break if COMMAND prints a newline, followed by the value of ;; decoding command must be specified. However, if the method ;; _also_ specifies an encoding function, then that is used for ;; encoding the contents of the tmp file. - (cond (copy-program - ;; The following should be changed. We need a more general - ;; mechanism to parse extra host args. - (when (string-match "\\([^#]*\\)#\\(.*\\)" host) - (setq copy-args (cons "-p" (cons (match-string 2 host) - rsh-args))) - (setq host (match-string 1 host))) - - ;; use rcp-like program for file transfer - (let ((argl (append copy-args - (list - tmpfil - (tramp-make-copy-program-file-name - user host - (tramp-shell-quote-argument localname)))))) - (tramp-message-for-buffer - multi-method method user host - 6 "Writing tmp file using `%s'..." copy-program) - (save-excursion (set-buffer trampbuf) (erase-buffer)) - (when tramp-debug-buffer - (save-excursion - (set-buffer (tramp-get-debug-buffer multi-method - method user host)) - (goto-char (point-max)) - (tramp-insert-with-face - 'bold (format "$ %s %s\n" copy-program - (mapconcat 'identity argl " "))))) - (unless (equal 0 - (apply #'call-process - copy-program nil trampbuf nil argl)) - (pop-to-buffer trampbuf) - (error - "Cannot write region to file `%s', command `%s' failed" - filename copy-program)) - (tramp-message-for-buffer - multi-method method user host - 6 "Transferring file using `%s'...done" - copy-program))) + (cond ((tramp-method-out-of-band-p multi-method method user host) + ;; `copy-file' handles out-of-band methods + (copy-file tmpfil filename t t)) + ((and rem-enc rem-dec) ;; Use inline file transfer (let ((tmpbuf (get-buffer-create " *tramp file transfer*"))) @@ -3306,7 +3546,8 @@ This will break if COMMAND prints a newline, followed by the value of (progn (tramp-message-for-buffer multi-method method user host - 6 "Encoding region using function...") + 6 "Encoding region using function `%s'..." + (symbol-name loc-enc)) (insert-file-contents-literally tmpfil) ;; CCC. The following `let' is a workaround for ;; the base64.el that comes with pgnus-0.84. If @@ -3672,11 +3913,12 @@ necessary anymore." ;; shouldn't have partial tramp file name syntax. Maybe another variable should ;; be introduced overwriting this check in such cases. Or we change tramp ;; file name syntax in order to avoid ambiguities, like in XEmacs ... -;; In case of XEmacs it can be always true (and wouldn't be necessary). +;; In case of non unified file names it can be always true (and wouldn't be +;; necessary, because there are different regexp). (defun tramp-completion-mode (file) "Checks whether method / user name / host name completion is active." (cond - ((featurep 'xemacs) t) + ((not tramp-unified-filenames) t) ((string-match "^/.*:.*:$" file) nil) ((string-match (concat tramp-prefix-regexp @@ -3684,11 +3926,21 @@ necessary anymore." file) (member (match-string 1 file) (mapcar 'car tramp-methods))) ((or (equal last-input-event 'tab) + ;; Emacs (and (integerp last-input-event) (not (event-modifiers last-input-event)) (or (char-equal last-input-event ?\?) (char-equal last-input-event ?\t) ; handled by 'tab already? - (char-equal last-input-event ?\ )))) + (char-equal last-input-event ?\ ))) + ;; XEmacs + (and (featurep 'xemacs) + (not (event-modifiers last-input-event)) + (or (char-equal + (funcall 'event-to-character last-input-event) ?\?) + (char-equal + (funcall 'event-to-character last-input-event) ?\t) + (char-equal + (funcall 'event-to-character last-input-event) ?\ )))) t))) (defun tramp-completion-handle-file-exists-p (filename) @@ -4037,6 +4289,35 @@ User is always nil." (forward-line 1)) result)) +(defun tramp-parse-shostkeys (dirname) + "Return a list of (user host) tuples allowed to access. +User is always nil." + + (let ((regexp (concat "^key_[0-9]+_\\(" tramp-host-regexp "\\)\\.pub$")) + (files (when (file-directory-p dirname) (directory-files dirname))) + result) + + (while files + (when (string-match regexp (car files)) + (push (list nil (match-string 1 (car files))) result)) + (setq files (cdr files))) + result)) + +(defun tramp-parse-sknownhosts (dirname) + "Return a list of (user host) tuples allowed to access. +User is always nil." + + (let ((regexp (concat "^\\(" tramp-host-regexp + "\\)\\.ssh-\\(dss\\|rsa\\)\\.pub$")) + (files (when (file-directory-p dirname) (directory-files dirname))) + result) + + (while files + (when (string-match regexp (car files)) + (push (list nil (match-string 1 (car files))) result)) + (setq files (cdr files))) + result)) + (defun tramp-parse-hosts (filename) "Return a list of (user host) tuples allowed to access. User is always nil." @@ -4193,14 +4474,29 @@ hosts, or files, disagree." (or switch "") (tramp-shell-quote-argument localname2)))))) +(defun tramp-touch (file time) + "Set the last-modified timestamp of the given file. +TIME is an Emacs internal time value as returned by `current-time'." + (let ((touch-time (format-time-string "%Y%m%d%H%M.%S" time))) + (with-parsed-tramp-file-name file nil + (let ((buf (tramp-get-buffer multi-method method user host))) + (unless (zerop (tramp-send-command-and-check + multi-method method user host + (format "touch -t %s %s" + touch-time + localname))) + (pop-to-buffer buf) + (error "tramp-touch: touch failed, see buffer `%s' for details" + buf)))))) + (defun tramp-buffer-name (multi-method method user host) "A name for the connection buffer for USER at HOST using METHOD." (if multi-method (tramp-buffer-name-multi-method "tramp" multi-method method user host) (let ((method (tramp-find-method multi-method method user host))) (if user - (format "*tramp/%s %s@%s*" method user host)) - (format "*tramp/%s %s*" method host)))) + (format "*tramp/%s %s@%s*" method user host) + (format "*tramp/%s %s*" method host))))) (defun tramp-buffer-name-multi-method (prefix multi-method method user host) "A name for the multi method connection buffer. @@ -4402,7 +4698,8 @@ file exists and nonzero exit status otherwise." 9 "Setting remote shell prompt...done") ) (t (tramp-message 5 "Remote `%s' groks tilde expansion, good" - (tramp-get-remote-sh multi-method method user host)))))) + (tramp-get-method-parameter + multi-method method user host 'tramp-remote-sh)))))) (defun tramp-check-ls-command (multi-method method user host cmd) "Checks whether the given `ls' executable groks `-n'. @@ -4468,11 +4765,6 @@ Returns nil if none was found, else the command is returned." (defun tramp-action-password (p multi-method method user host) "Query the user for a password." (let ((pw-prompt (match-string 0))) - (when (tramp-method-out-of-band-p multi-method method user host) - (kill-process (get-buffer-process (current-buffer))) - (error (concat "Out of band method `%s' not applicable " - "for remote shell asking for a password") - method)) (tramp-message 9 "Sending password") (tramp-enter-password p pw-prompt))) @@ -4583,6 +4875,7 @@ The terminal type can be configured with `tramp-terminal-type'." p multi-method method user host actions) nil))) (unless (eq exit 'ok) + (tramp-clear-passwd user host) (error "Login failed")))) ;; For multi-actions. @@ -4618,6 +4911,7 @@ The terminal type can be configured with `tramp-terminal-type'." (tramp-process-one-multi-action p method user host actions) nil))) (unless (eq exit 'ok) + (tramp-clear-passwd user host) (error "Login failed")))) ;; Functions to execute when we have seen the remote shell prompt but @@ -4686,15 +4980,15 @@ Maybe the different regular expressions need to be tuned. (p (apply 'start-process (tramp-buffer-name multi-method method user host) (tramp-get-buffer multi-method method user host) - (tramp-get-login-program + (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host) + user host 'tramp-login-program) host - (tramp-get-login-args + (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host))) + user host 'tramp-login-args))) (found nil) (pw nil)) (process-kill-without-query p) @@ -4743,18 +5037,18 @@ arguments, and xx will be used as the host name to connect to. (let ((process-environment (copy-sequence process-environment)) (bufnam (tramp-buffer-name multi-method method user host)) (buf (tramp-get-buffer multi-method method user host)) - (login-program (tramp-get-login-program + (login-program (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host)) - (login-args (tramp-get-login-args + user host 'tramp-login-program)) + (login-args (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host))) + user host 'tramp-login-args))) ;; The following should be changed. We need a more general ;; mechanism to parse extra host args. (when (string-match "\\([^#]*\\)#\\(.*\\)" host) - (setq login-args (cons "-p" (cons (match-string 2 host) rsh-args))) + (setq login-args (cons "-p" (cons (match-string 2 host) login-args))) (setq host (match-string 1 host))) (setenv "TERM" tramp-terminal-type) (let* ((default-directory (tramp-temporary-file-directory)) @@ -4818,17 +5112,17 @@ prompt than you do, so it is not at all unlikely that the variable (p (apply 'start-process (tramp-buffer-name multi-method method user host) (tramp-get-buffer multi-method method user host) - (tramp-get-login-program + (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host) + user host 'tramp-login-program) (mapcar (lambda (x) (format-spec x `((?u . ,(or user "root"))))) - (tramp-get-login-args + (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host)))) + user host 'tramp-login-args)))) (found nil) (pw nil)) (process-kill-without-query p) @@ -5054,11 +5348,13 @@ Uses PROMPT as a prompt and sends the password to process P." (erase-buffer) (process-send-string p (concat pw - (tramp-get-password-end-of-line - tramp-current-multi-method - tramp-current-method - tramp-current-user - tramp-current-host))))) + (or (tramp-get-method-parameter + tramp-current-multi-method + tramp-current-method + tramp-current-user + tramp-current-host + 'tramp-password-end-of-line) + tramp-default-password-end-of-line))))) ;; HHH: Not Changed. This might handle the case where USER is not ;; given in the "File name" very poorly. Then, the local @@ -5101,13 +5397,15 @@ to set up. METHOD, USER and HOST specify the connection." (tramp-send-command-internal multi-method method user host (format "exec env 'ENV=' 'PS1=$ ' %s" - (tramp-get-remote-sh multi-method method user host)) + (tramp-get-method-parameter + multi-method method user host 'tramp-remote-sh)) (format "remote `%s' to come up" - (tramp-get-remote-sh multi-method method user host))) + (tramp-get-method-parameter + multi-method method user host 'tramp-remote-sh))) (tramp-barf-if-no-shell-prompt p 30 "Remote `%s' didn't come up. See buffer `%s' for details" - (tramp-get-remote-sh multi-method method user host) + (tramp-get-method-parameter multi-method method user host 'tramp-remote-sh) (buffer-name)) (tramp-message 8 "Setting up remote shell environment") (tramp-discard-garbage-erase-buffer p multi-method method user host) @@ -5287,13 +5585,10 @@ locale to C and sets up the remote shell search path." multi-method method user host (concat "tramp_file_attributes () {\n" tramp-remote-perl - " -e '" tramp-perl-file-attributes "' $1 2>/dev/null\n" + " -e '" tramp-perl-file-attributes "' $1 $2 2>/dev/null\n" "}")) (tramp-wait-for-output) - (unless (tramp-get-copy-program - multi-method - (tramp-find-method multi-method method user host) - user host) + (unless (tramp-method-out-of-band-p multi-method method user host) (tramp-message 5 "Sending the Perl `mime-encode' implementations.") (tramp-send-string multi-method method user host @@ -5332,10 +5627,7 @@ locale to C and sets up the remote shell search path." (tramp-set-connection-property "ln" ln multi-method method user host))) (erase-buffer) ;; Find the right encoding/decoding commands to use. - (unless (tramp-get-copy-program - multi-method - (tramp-find-method multi-method method user host) - user host) + (unless (tramp-method-out-of-band-p multi-method method user host) (tramp-find-inline-encoding multi-method method user host)) ;; If encoding/decoding command are given, test to see if they work. ;; CCC: Maybe it would be useful to run the encoder both locally and @@ -5548,11 +5840,12 @@ connection if a previous connection has died for some reason." (unless (and p (processp p) (memq (process-status p) '(run open))) (when (and p (processp p)) (delete-process p)) - (funcall (tramp-get-connection-function - multi-method - (tramp-find-method multi-method method user host) - user host) - multi-method method user host)))) + (let ((process-connection-type tramp-process-connection-type)) + (funcall (tramp-get-method-parameter + multi-method + (tramp-find-method multi-method method user host) + user host 'tramp-connection-function) + multi-method method user host))))) (defun tramp-send-command (multi-method method user host command &optional noerase neveropen) @@ -6035,10 +6328,10 @@ If both MULTI-METHOD and METHOD are nil, do a lookup in "Return t if this is an out-of-band method, nil otherwise. It is important to check for this condition, since it is not possible to enter a password for the `tramp-copy-program'." - (tramp-get-copy-program + (tramp-get-method-parameter multi-method (tramp-find-method multi-method method user host) - user host)) + user host 'tramp-copy-program)) ;; Variables local to connection. @@ -6117,65 +6410,19 @@ If the value is not set for the connection, return `default'" (tramp-get-connection-property "local-decoding" nil multi-method method user host)) - - -(defun tramp-get-connection-function (multi-method method user host) - (second (or (assoc 'tramp-connection-function - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify a connection function" - (or multi-method method))))) - -(defun tramp-get-remote-sh (multi-method method user host) - (second (or (assoc 'tramp-remote-sh - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify a remote shell" - (or multi-method method))))) - -(defun tramp-get-login-program (multi-method method user host) - (second (or (assoc 'tramp-login-program - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify a login program" - (or multi-method method))))) - -(defun tramp-get-login-args (multi-method method user host) - (second (or (assoc 'tramp-login-args - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify login args" - (or multi-method method))))) - -(defun tramp-get-copy-program (multi-method method user host) - (second (or (assoc 'tramp-copy-program - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify a copy program" - (or multi-method method))))) - -(defun tramp-get-copy-args (multi-method method user host) - (second (or (assoc 'tramp-copy-args - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify copy args" - (or multi-method method))))) - -(defun tramp-get-copy-keep-date-arg (multi-method method user host) - (second (or (assoc 'tramp-copy-keep-date-arg - (assoc (tramp-find-method multi-method method user host) - tramp-methods)) - (error "Method `%s' didn't specify `keep-date' arg for tramp" - (or multi-method method))))) - -(defun tramp-get-password-end-of-line (multi-method method user host) - (let ((entry (assoc 'tramp-password-end-of-line +(defun tramp-get-method-parameter (multi-method method user host param) + "Return the method parameter PARAM. +If the `tramp-methods' entry does not exist, use the variable PARAM +as default." + (unless (boundp param) + (error "Non-existing method parameter `%s'" param)) + (let ((entry (assoc param (assoc (tramp-find-method multi-method method user host) tramp-methods)))) - (unless entry - (error "Method `%s' didn't specify `password-end-of-line' arg for tramp" - (or multi-method method))) - (or (second entry) tramp-default-password-end-of-line))) + (if entry + (second entry) + (symbol-value param)))) + ;; Auto saving to a special directory. @@ -6251,10 +6498,28 @@ this is the function `temp-directory'." (defun tramp-read-passwd (prompt) "Read a password from user (compat function). -Invokes `read-passwd' if that is defined, else `ange-ftp-read-passwd'." - (apply - (if (fboundp 'read-passwd) #'read-passwd #'ange-ftp-read-passwd) - (list prompt))) +Invokes `password-read' if available, `read-passwd' else." + (if (functionp 'password-read) + (let* ((user (or tramp-current-user (user-login-name))) + (host (or tramp-current-host (system-name))) + (key (concat user "@" host)) + (password (apply #'password-read (list prompt key)))) + (apply #'password-cache-add (list key password)) + password) + (read-passwd prompt))) + +(defun tramp-clear-passwd (&optional user host) + "Clear password cache for connection related to current-buffer." + (interactive) + (let ((filename (or buffer-file-name list-buffers-directory ""))) + (when (and (functionp 'password-cache-remove) + (or (and user host) (tramp-tramp-file-p filename))) + (let* ((v (when (tramp-tramp-file-p filename) + (tramp-dissect-file-name filename))) + (luser (or user (tramp-file-name-user v) (user-login-name))) + (lhost (or host (tramp-file-name-host v) (system-name))) + (key (concat luser "@" lhost))) + (apply #'password-cache-remove (list key)))))) (defun tramp-time-diff (t1 t2) "Return the difference between the two times, in seconds. @@ -6626,6 +6891,7 @@ report. ;; ** Enhance variables for debug. ;; ** Implement "/multi:" completion. ;; ** Add a learning mode for completion. Make results persistent. +;; * Allow out-of-band methods as _last_ multi-hop. ;; Functions for file-name-handler-alist: ;; diff-latest-backup-file -- in diff.el @@ -6642,4 +6908,5 @@ report. ;; unhandled-file-name-directory ;; vc-registered +;;; arch-tag: 3a21a994-182b-48fa-b0cd-c1d9fede424a ;;; tramp.el ends here diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index f741da82757..b3223d7a46e 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -30,7 +30,7 @@ ;; are auto-frobbed from configure.ac, so you should edit that file and run ;; "autoconf && ./configure" to change them. -(defconst tramp-version "2.0.36" +(defconst tramp-version "2.0.39" "This version of Tramp.") (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org" @@ -38,4 +38,5 @@ (provide 'trampver) +;;; arch-tag: 443576ca-f8f1-4bb1-addc-5c70861e93b1 ;;; trampver.el ends here diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el index 4c701b48ac5..3f004b8864e 100644 --- a/lisp/net/webjump.el +++ b/lisp/net/webjump.el @@ -1,6 +1,6 @@ ;;; webjump.el --- programmable Web hotlist -;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1996, 1997, 2004 Free Software Foundation, Inc. ;; Author: Neil W. Van Dyke <nwv@acm.org> ;; Created: 09-Aug-1996 @@ -300,7 +300,8 @@ Please submit bug reports and other feedback to the author, Neil W. Van Dyke ((eq builtin 'mirrors) (if (= (length expr) 1) (error - "WebJump URL builtin \"mirrors\" for \"%s\" needs at least 1 arg")) + "WebJump URL builtin \"mirrors\" for \"%s\" needs at least 1 arg" + name)) (webjump-choose-mirror name (cdr (append expr nil)))) ((eq builtin 'name) name) @@ -400,4 +401,5 @@ Please submit bug reports and other feedback to the author, Neil W. Van Dyke (provide 'webjump) +;;; arch-tag: f1d20156-0a6f-488b-bd91-f69ee8b6d5cc ;;; webjump.el ends here diff --git a/lisp/net/zone-mode.el b/lisp/net/zone-mode.el index a58bc2dd54a..6b4d22f9b13 100644 --- a/lisp/net/zone-mode.el +++ b/lisp/net/zone-mode.el @@ -92,7 +92,7 @@ Zone-mode does two things: - fontification" - (add-hook 'write-file-hooks 'zone-mode-update-serial-hook nil t) + (add-hook 'write-file-functions 'zone-mode-update-serial-hook nil t) (if (null zone-mode-syntax-table) (zone-mode-load-time-setup)) ;; should have been run at load-time @@ -115,4 +115,5 @@ Zone-mode does two things: (provide 'zone-mode) +;;; arch-tag: 6a2940ef-fd4f-4de7-b979-b027b09821fe ;;; zone-mode.el ends here |