* net/tramp.el (tramp-handle-insert-file-contents): Use "dd"
[bpt/emacs.git] / lisp / net / tramp.el
index 6fe176f..bc831c3 100644 (file)
@@ -1,7 +1,6 @@
 ;;; tramp.el --- Transparent Remote Access, Multiple Protocol
 
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-;;   2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2011 Free Software Foundation, Inc.
 
 ;; Author: Kai Großjohann <kai.grossjohann@gmx.net>
 ;;         Michael Albinus <michael.albinus@gmx.de>
@@ -298,6 +297,7 @@ shouldn't return t when it isn't."
         (executable-find "pscp"))
     (if        (or (fboundp 'password-read)
            (fboundp 'auth-source-user-or-password)
+           (fboundp 'auth-source-search)
            ;; Pageant is running.
            (tramp-compat-process-running-p "Pageant"))
        "pscp"
@@ -308,6 +308,7 @@ shouldn't return t when it isn't."
      ((tramp-detect-ssh-controlmaster) "scpc")
      ((or (fboundp 'password-read)
          (fboundp 'auth-source-user-or-password)
+         (fboundp 'auth-source-search)
          ;; ssh-agent is running.
          (getenv "SSH_AUTH_SOCK")
          (getenv "SSH_AGENT_PID"))
@@ -661,12 +662,12 @@ Should always start with \"^\". Derived from `tramp-prefix-format'.")
        ((equal tramp-syntax 'sep) "/")
        ((equal tramp-syntax 'url) "://")
        (t (error "Wrong `tramp-syntax' defined")))
-  "*String matching delimeter between method and user or host names.
+  "*String matching delimiter between method and user or host names.
 Used in `tramp-make-tramp-file-name'.")
 
 (defconst tramp-postfix-method-regexp
   (regexp-quote tramp-postfix-method-format)
-  "*Regexp matching delimeter between method and user or host names.
+  "*Regexp matching delimiter between method and user or host names.
 Derived from `tramp-postfix-method-format'.")
 
 (defconst tramp-user-regexp "[^:/ \t]+"
@@ -674,12 +675,12 @@ Derived from `tramp-postfix-method-format'.")
 
 ;;;###tramp-autoload
 (defconst tramp-prefix-domain-format "%"
-  "*String matching delimeter between user and domain names.")
+  "*String matching delimiter between user and domain names.")
 
 ;;;###tramp-autoload
 (defconst tramp-prefix-domain-regexp
   (regexp-quote tramp-prefix-domain-format)
-  "*Regexp matching delimeter between user and domain names.
+  "*Regexp matching delimiter between user and domain names.
 Derived from `tramp-prefix-domain-format'.")
 
 (defconst tramp-domain-regexp "[-a-zA-Z0-9_.]+"
@@ -692,12 +693,12 @@ Derived from `tramp-prefix-domain-format'.")
   "*Regexp matching user names with domain names.")
 
 (defconst tramp-postfix-user-format "@"
-  "*String matching delimeter between user and host names.
+  "*String matching delimiter between user and host names.
 Used in `tramp-make-tramp-file-name'.")
 
 (defconst tramp-postfix-user-regexp
   (regexp-quote tramp-postfix-user-format)
-  "*Regexp matching delimeter between user and host names.
+  "*Regexp matching delimiter between user and host names.
 Derived from `tramp-postfix-user-format'.")
 
 (defconst tramp-host-regexp "[a-zA-Z0-9_.-]+"
@@ -741,11 +742,11 @@ Derived from `tramp-postfix-ipv6-format'.")
        ((equal tramp-syntax 'sep) "#")
        ((equal tramp-syntax 'url) ":")
        (t (error "Wrong `tramp-syntax' defined")))
-  "*String matching delimeter between host names and port numbers.")
+  "*String matching delimiter between host names and port numbers.")
 
 (defconst tramp-prefix-port-regexp
   (regexp-quote tramp-prefix-port-format)
-  "*Regexp matching delimeter between host names and port numbers.
+  "*Regexp matching delimiter between host names and port numbers.
 Derived from `tramp-prefix-port-format'.")
 
 (defconst tramp-port-regexp "[0-9]+"
@@ -762,12 +763,12 @@ Derived from `tramp-prefix-port-format'.")
        ((equal tramp-syntax 'sep) "]")
        ((equal tramp-syntax 'url) "")
        (t (error "Wrong `tramp-syntax' defined")))
-  "*String matching delimeter between host names and localnames.
+  "*String matching delimiter between host names and localnames.
 Used in `tramp-make-tramp-file-name'.")
 
 (defconst tramp-postfix-host-regexp
   (regexp-quote tramp-postfix-host-format)
-  "*Regexp matching delimeter between host names and localnames.
+  "*Regexp matching delimiter between host names and localnames.
 Derived from `tramp-postfix-host-format'.")
 
 (defconst tramp-localname-regexp ".*$"
@@ -1573,8 +1574,12 @@ special handling of `substitute-in-file-name'."
     (let ((props (tramp-compat-funcall
                  'overlay-properties (symbol-value 'rfn-eshadow-overlay))))
       (while props
-       (tramp-compat-funcall
-        'overlay-put tramp-rfn-eshadow-overlay (pop props) (pop props))))))
+       ;; The `field' property prevents correct minibuffer
+       ;; completion; we exclude it.
+       (if (not (eq (car props) 'field))
+           (tramp-compat-funcall
+            'overlay-put tramp-rfn-eshadow-overlay (pop props) (pop props))
+         (pop props) (pop props))))))
 
 (when (boundp 'rfn-eshadow-setup-minibuffer-hook)
   (add-hook 'rfn-eshadow-setup-minibuffer-hook
@@ -1862,7 +1867,7 @@ Falls back to normal file name handler if no Tramp file name handler exists."
                (condition-case err
                    (apply foreign operation args)
 
-                 ;; Trace, that somebody has interrupted the operation.
+                 ;; Trace that somebody has interrupted the operation.
                  (quit
                   (let (tramp-message-show-message)
                     (tramp-message
@@ -2320,7 +2325,7 @@ remote host and localname (filename on remote host)."
        (vector method user host localname)))))
 
 ;; This function returns all possible method completions, adding the
-;; trailing method delimeter.
+;; trailing method delimiter.
 (defun tramp-get-completion-methods (partial-method)
   "Returns all method completions for PARTIAL-METHOD."
   (mapcar
@@ -2833,16 +2838,16 @@ User is always nil."
                 v
                 (cond
                  ((and beg end)
-                  (format "tail -c +%d %s | head -c +%d >%s"
-                          (1+ beg) (tramp-shell-quote-argument localname)
+                  (format "dd bs=1 skip=%d if=%s count=%d of=%s"
+                          beg (tramp-shell-quote-argument localname)
                           (- end beg) remote-copy))
                  (beg
-                  (format "tail -c +%d %s >%s"
-                          (1+ beg) (tramp-shell-quote-argument localname)
+                  (format "dd bs=1 skip=%d if=%s of=%s"
+                          beg (tramp-shell-quote-argument localname)
                           remote-copy))
                  (end
-                  (format "head -c +%d %s >%s"
-                          (1+ end) (tramp-shell-quote-argument localname)
+                  (format "dd bs=1 count=%d if=%s of=%s"
+                          end (tramp-shell-quote-argument localname)
                           remote-copy)))))
 
              ;; `insert-file-contents-literally' takes care to avoid
@@ -2938,7 +2943,7 @@ User is always nil."
 (defun tramp-handle-substitute-in-file-name (filename)
   "Like `substitute-in-file-name' for Tramp files.
 \"//\" and \"/~\" substitute only in the local filename part.
-If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at
+If the URL Tramp syntax is chosen, \"//\" as method delimiter and \"/~\" at
 beginning of local filename are not substituted."
   ;; First, we must replace environment variables.
   (setq filename (tramp-replace-environment-variables filename))
@@ -3093,8 +3098,11 @@ The terminal type can be configured with `tramp-terminal-type'."
          (setq found (funcall action proc vec)))))
     found))
 
-(defun tramp-process-actions (proc vec actions &optional timeout)
-  "Perform actions until success or TIMEOUT."
+(defun tramp-process-actions (proc vec pos actions &optional timeout)
+  "Perform ACTIONS until success or TIMEOUT.
+PROC and VEC indicate the remote connection to be used.  POS, if
+set, is the starting point of the region to be deleted in the
+connection buffer."
   ;; Preserve message for `progress-reporter'.
   (tramp-compat-with-temp-message ""
     ;; Enable auth-source and password-cache.
@@ -3119,7 +3127,10 @@ The terminal type can be configured with `tramp-terminal-type'."
           (cond
            ((eq exit 'permission-denied) "Permission denied")
            ((eq exit 'process-died) "Process died")
-           (t "Login failed"))))))))
+           (t "Login failed"))))
+       (when (numberp pos)
+         (with-current-buffer (tramp-get-connection-buffer vec)
+           (let (buffer-read-only) (delete-region pos (point)))))))))
 
 :;; Utility functions:
 
@@ -3520,17 +3531,32 @@ Invokes `password-read' if available, `read-passwd' else."
          (or prompt
              (with-current-buffer (process-buffer proc)
                (tramp-check-for-regexp proc tramp-password-prompt-regexp)
-               (format "%s for %s " (capitalize (match-string 1)) key)))))
+               (format "%s for %s " (capitalize (match-string 1)) key))))
+         auth-info auth-passwd)
     (with-parsed-tramp-file-name key nil
       (prog1
          (or
-          ;; See if auth-sources contains something useful, if it's bound.
+          ;; See if auth-sources contains something useful, if it's
+          ;; bound.  `auth-source-user-or-password' is an obsoleted
+          ;; function, it has been replaced by `auth-source-search'.
           (and (boundp 'auth-sources)
                (tramp-get-connection-property v "first-password-request" nil)
                ;; Try with Tramp's current method.
-               (tramp-compat-funcall
-                'auth-source-user-or-password
-                "password" tramp-current-host tramp-current-method))
+                (if (fboundp 'auth-source-search)
+                   (setq auth-info
+                            (tramp-compat-funcall
+                             'auth-source-search
+                             :max 1
+                             :user (or tramp-current-user t)
+                             :host tramp-current-host
+                             :port tramp-current-method)
+                           auth-passwd (plist-get (nth 0 auth-info) :secret)
+                           auth-passwd (if (functionp auth-passwd)
+                                            (funcall auth-passwd)
+                                          auth-passwd))
+                  (tramp-compat-funcall
+                   'auth-source-user-or-password
+                   "password" tramp-current-host tramp-current-method)))
           ;; Try the password cache.
           (when (functionp 'password-read)
             (unless (tramp-get-connection-property