]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp-sh.el
Fix an utf8 problem for Tramp on BSD
[gnu-emacs] / lisp / net / tramp-sh.el
index 433b2ba09c7d4edde2c5b2743f1b25499c67399d..c1df1c602d5caacb18ee142f50fc3d7cd038d4e1 100644 (file)
@@ -621,10 +621,7 @@ if (!$result) {
     $result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\");
 }
 
-if ($ARGV[0] =~ /\\/$/) {
-    $result = $result . \"/\";
-}
-
+$result =~ s/\"/\\\\\"/g;
 print \"\\\"$result\\\"\\n\";
 ' \"$1\" 2>/dev/null"
   "Perl script to produce output suitable for use with `file-truename'
@@ -993,10 +990,10 @@ of command line.")
     (file-acl . tramp-sh-handle-file-acl)
     (file-attributes . tramp-sh-handle-file-attributes)
     (file-directory-p . tramp-sh-handle-file-directory-p)
-    ;; `file-equal-p' performed by default handler.
+    (file-equal-p . tramp-handle-file-equal-p)
     (file-executable-p . tramp-sh-handle-file-executable-p)
     (file-exists-p . tramp-sh-handle-file-exists-p)
-    ;; `file-in-directory-p' performed by default handler.
+    (file-in-directory-p . tramp-handle-file-in-directory-p)
     (file-local-copy . tramp-sh-handle-file-local-copy)
     (file-modes . tramp-handle-file-modes)
     (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
@@ -1143,20 +1140,17 @@ target of the symlink differ."
 
           ;; Do it yourself.  We bind `directory-sep-char' here for
           ;; XEmacs on Windows, which would otherwise use backslash.
-          (t (let* ((directory-sep-char ?/)
-                    (steps (tramp-compat-split-string localname "/"))
-                    (localnamedir (tramp-run-real-handler
-                                   'file-name-as-directory (list localname)))
-                    (is-dir (string= localname localnamedir))
-                    (thisstep nil)
-                    (numchase 0)
-                    ;; Don't make the following value larger than
-                    ;; necessary.  People expect an error message in
-                    ;; a timely fashion when something is wrong;
-                    ;; otherwise they might think that Emacs is hung.
-                    ;; Of course, correctness has to come first.
-                    (numchase-limit 20)
-                    symlink-target)
+          (t (let ((directory-sep-char ?/)
+                   (steps (tramp-compat-split-string localname "/"))
+                   (thisstep nil)
+                   (numchase 0)
+                   ;; Don't make the following value larger than
+                   ;; necessary.  People expect an error message in a
+                   ;; timely fashion when something is wrong;
+                   ;; otherwise they might think that Emacs is hung.
+                   ;; Of course, correctness has to come first.
+                   (numchase-limit 20)
+                   symlink-target)
                (while (and steps (< numchase numchase-limit))
                  (setq thisstep (pop steps))
                  (tramp-message
@@ -1212,10 +1206,8 @@ target of the symlink differ."
                      (if result
                          (mapconcat 'identity (cons "" result) "/")
                        "/"))
-               (when (and is-dir
-                          (or (string= "" result)
-                              (not (string= (substring result -1) "/"))))
-                 (setq result (concat result "/"))))))
+               (when (string= "" result)
+                 (setq result "/")))))
 
          (tramp-message v 4 "True name of `%s' is `%s'" localname result)
          result))))
@@ -1278,8 +1270,12 @@ target of the symlink differ."
             (tramp-get-ls-command vec)
             ;; On systems which have no quoting style, file names
             ;; with special characters could fail.
-            (if (tramp-get-ls-command-with-quoting-style vec)
-                "--quoting-style=c" "")
+            (cond
+             ((tramp-get-ls-command-with-quoting-style vec)
+              "--quoting-style=c")
+             ((tramp-get-ls-command-with-w-option vec)
+              "-w")
+             (t ""))
             (if (eq id-format 'integer) "-ildn" "-ild")
             (tramp-shell-quote-argument localname)))
     ;; Parse `ls -l' output ...
@@ -1837,10 +1833,14 @@ be non-negative integers."
      "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
-    ;; On systems which have no quoting style, file names with
-    ;; special characters could fail.
-    (if (tramp-get-ls-command-with-quoting-style vec)
-       "--quoting-style=shell" "")
+    ;; On systems which have no quoting style, file names with special
+    ;; characters could fail.
+    (cond
+     ((tramp-get-ls-command-with-quoting-style vec)
+      "--quoting-style=shell")
+     ((tramp-get-ls-command-with-w-option vec)
+      "-w")
+     (t ""))
     (tramp-get-remote-stat vec)
     tramp-stat-marker tramp-stat-marker
     tramp-stat-marker tramp-stat-marker
@@ -2457,16 +2457,17 @@ The method used must be an out-of-band method."
        (setq source (if t1
                         (tramp-make-copy-program-file-name v)
                       (shell-quote-argument filename))
-             target (funcall
+          target (if t2
+                     (tramp-make-copy-program-file-name v)
+                   (shell-quote-argument
+                    (funcall
                      (if (and (file-directory-p filename)
                               (string-equal
                                (file-name-nondirectory filename)
                                (file-name-nondirectory newname)))
                          'file-name-directory
                        'identity)
-                     (if t2
-                         (tramp-make-copy-program-file-name v)
-                       (shell-quote-argument newname))))
+                     newname))))
 
        ;; Check for host and port number.  We cannot use
        ;; `tramp-file-name-port', because this returns also
@@ -4148,12 +4149,14 @@ seconds.  If not, it produces an error message with the given ERROR-ARGS."
   "Set up an interactive shell.
 Mainly sets the prompt and the echo correctly.  PROC is the shell
 process to set up.  VEC specifies the connection."
-  (let ((tramp-end-of-output tramp-initial-end-of-output))
+  (let ((tramp-end-of-output tramp-initial-end-of-output)
+       (case-fold-search t))
     (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
 
     ;; Disable tab and echo expansion.
     (tramp-message vec 5 "Setting up remote shell environment")
-    (tramp-send-command vec "stty tab0 -inlcr -echo kill '^U' erase '^H'" t)
+    (tramp-send-command
+     vec "stty tab0 -inlcr -onlcr -echo kill '^U' erase '^H'" t)
     ;; Check whether the echo has really been disabled.  Some
     ;; implementations, like busybox of embedded GNU/Linux, don't
     ;; support disabling.
@@ -4180,7 +4183,7 @@ process to set up.  VEC specifies the connection."
        ;; Use MULE to select the right EOL convention for communicating
        ;; with the process.
        (let ((cs (or (and (memq 'utf-8 (coding-system-list))
-                          (string-match "utf8" (tramp-get-remote-locale vec))
+                          (string-match "utf-?8" (tramp-get-remote-locale vec))
                           (cons 'utf-8 'utf-8))
                      (tramp-compat-funcall 'process-coding-system proc)
                      (cons 'undecided 'undecided)))
@@ -4262,7 +4265,7 @@ process to set up.  VEC specifies the connection."
   (tramp-find-shell vec)
 
   ;; Disable unexpected output.
-  (tramp-send-command vec "mesg n; biff n" t)
+  (tramp-send-command vec "mesg n 2>/dev/null; biff n 2>/dev/null" t)
 
   ;; IRIX64 bash expands "!" even when in single quotes.  This
   ;; destroys our shell functions, we must disable it.  See
@@ -5293,21 +5296,26 @@ Return ATTR."
            ;; The login shell could return more than just the $PATH
            ;; string.  So we use `tramp-end-of-heredoc' as marker.
            (when elt2
-             (tramp-send-command-and-read
-              vec
-              (format
-               "%s %s %s 'echo %s \\\"$PATH\\\"'"
-               (tramp-get-method-parameter vec 'tramp-remote-shell)
-               (mapconcat
-                'identity
-                (tramp-get-method-parameter vec 'tramp-remote-shell-login)
-                " ")
-               (mapconcat
-                'identity
-                (tramp-get-method-parameter vec 'tramp-remote-shell-args)
-                " ")
-               (tramp-shell-quote-argument tramp-end-of-heredoc))
-              nil (regexp-quote tramp-end-of-heredoc)))))
+             (or
+              (tramp-send-command-and-read
+               vec
+               (format
+                "%s %s %s 'echo %s \\\"$PATH\\\"'"
+                (tramp-get-method-parameter vec 'tramp-remote-shell)
+                (mapconcat
+                 'identity
+                 (tramp-get-method-parameter vec 'tramp-remote-shell-login)
+                 " ")
+                (mapconcat
+                 'identity
+                 (tramp-get-method-parameter vec 'tramp-remote-shell-args)
+                 " ")
+                (tramp-shell-quote-argument tramp-end-of-heredoc))
+               'noerror (regexp-quote tramp-end-of-heredoc))
+              (progn
+                (tramp-message
+                 vec 2 "Could not retrieve `tramp-own-remote-path'")
+                nil)))))
 
       ;; Replace place holder `tramp-default-remote-path'.
       (when elt1
@@ -5351,7 +5359,7 @@ Return ATTR."
 (defun tramp-get-remote-locale (vec)
   (with-tramp-connection-property vec "locale"
     (tramp-send-command vec "locale -a")
-    (let ((candidates '("en_US.utf8" "C.utf8"))
+    (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8"))
          locale)
       (with-current-buffer (tramp-get-connection-buffer vec)
        (while candidates
@@ -5410,6 +5418,14 @@ Return ATTR."
        vec (format "%s --quoting-style=shell -al /dev/null"
                   (tramp-get-ls-command vec))))))
 
+(defun tramp-get-ls-command-with-w-option (vec)
+  (save-match-data
+    (with-tramp-connection-property vec "ls-w-option"
+      (tramp-message vec 5 "Checking, whether `ls -w' works")
+      ;; Option "-w" is available on BSD systems.
+      (tramp-send-command-and-check
+       vec (format "%s -alw /dev/null" (tramp-get-ls-command vec))))))
+
 (defun tramp-get-test-command (vec)
   (with-tramp-connection-property vec "test"
     (tramp-message vec 5 "Finding a suitable `test' command")