From: Michael Albinus Date: Tue, 24 Mar 2015 19:05:00 +0000 (+0100) Subject: Improve special char handling in Tramp X-Git-Tag: emacs-25.0.90~2564^2~82 X-Git-Url: https://code.delx.au/gnu-emacs/commitdiff_plain/444975fa5493b962851b9a01749c22c99d2b0992 Improve special char handling in Tramp * net/tramp-sh.el (tramp-do-file-attributes-with-ls) (tramp-do-file-attributes-with-stat): Quote file names in output. (tramp-do-directory-files-and-attributes-with-stat): Use "//" as marker. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e91d2bc046..3b8fa7d66c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2015-03-24 Michael Albinus + + * net/tramp-sh.el (tramp-do-file-attributes-with-ls) + (tramp-do-file-attributes-with-stat): Quote file names in output. + (tramp-do-directory-files-and-attributes-with-stat): Use "//" as marker. + 2015-03-24 Daiki Ueno * epg.el (epg-start-generate-key): Fix typo in "gpg --gen-key" diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index b82b4deb21..f59c5fbdf6 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1175,15 +1175,19 @@ target of the symlink differ." (tramp-message vec 5 "file attributes with ls: %s" localname) (tramp-send-command vec - (format "(%s %s || %s -h %s) && %s %s %s" + (format "(%s %s || %s -h %s) && %s %s %s %s" (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) (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=c" "") (if (eq id-format 'integer) "-ildn" "-ild") (tramp-shell-quote-argument localname))) - ;; parse `ls -l' output ... + ;; Parse `ls -l' output ... (with-current-buffer (tramp-get-buffer vec) (when (> (buffer-size) 0) (goto-char (point-min)) @@ -1222,11 +1226,14 @@ target of the symlink differ." ;; From the file modes, figure out other stuff. (setq symlinkp (eq ?l (aref res-filemodes 0))) (setq dirp (eq ?d (aref res-filemodes 0))) - ;; if symlink, find out file name pointed to + ;; If symlink, find out file name pointed to. (when symlinkp (search-forward "-> ") - (setq res-symlink-target (buffer-substring (point) (point-at-eol)))) - ;; return data gathered + (setq res-symlink-target + (if (tramp-get-ls-command-with-quoting-style vec) + (read (current-buffer)) + (buffer-substring (point) (point-at-eol))))) + ;; Return data gathered. (list ;; 0. t for directory, string (name linked to) for symbolic ;; link, or nil. @@ -1249,9 +1256,9 @@ target of the symlink differ." ;; 8. File modes, as a string of ten letters or dashes as in ls -l. res-filemodes ;; 9. t if file's gid would change if file were deleted and - ;; recreated. Will be set in `tramp-convert-file-attributes' + ;; recreated. Will be set in `tramp-convert-file-attributes'. t - ;; 10. inode number. + ;; 10. Inode number. res-inode ;; 11. Device number. Will be replaced by a virtual device number. -1 @@ -1275,16 +1282,21 @@ target of the symlink differ." (tramp-send-command-and-read vec (format - ;; On Opsware, pdksh (which is the true name of ksh there) doesn't - ;; parse correctly the sequence "((". Therefore, we add a space. - "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' \"%s\" || echo nil)" + (concat + ;; On Opsware, pdksh (which is the true name of ksh there) + ;; doesn't parse correctly the sequence "((". Therefore, we add + ;; a space. Apostrophes in the stat output are masked as "//", + ;; in order to make a proper shell escape of them in file names. + "( (%s %s || %s -h %s) && (%s -c " + "'((//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " + "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g') || echo nil)") (tramp-get-file-exists-command vec) (tramp-shell-quote-argument localname) (tramp-get-test-command vec) (tramp-shell-quote-argument localname) (tramp-get-remote-stat vec) - (if (eq id-format 'integer) "%ue0" "\"%U\"") - (if (eq id-format 'integer) "%ge0" "\"%G\"") + (if (eq id-format 'integer) "%ue0" "//%U//") + (if (eq id-format 'integer) "%ge0" "//%G//") (tramp-shell-quote-argument localname)))) (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) @@ -1717,14 +1729,13 @@ be non-negative integers." (concat ;; We must care about file names with spaces, or starting with ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, - ;; but it does not work on all remote systems. Therefore, we - ;; use \000 as file separator. - ;; Apostrophes in the stat output are masked as ?/ characters, in - ;; order to make a proper shell escape of them in file names. + ;; but it does not work on all remote systems. Apostrophes in + ;; the stat output are masked as "//", in order to make a proper + ;; shell escape of them in file names. "cd %s && echo \"(\"; (%s %s -a | " "xargs %s -c " - "'(/%%n/ (/%%N/) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 /%%A/ t %%ie0 -1)' " - "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\//\"/g'); echo \")\"") + "'(//%%n// (//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " + "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g'); echo \")\"") (tramp-shell-quote-argument localname) (tramp-get-ls-command vec) ;; On systems which have no quoting style, file names with @@ -1732,8 +1743,8 @@ be non-negative integers." (if (tramp-get-ls-command-with-quoting-style vec) "--quoting-style=shell" "") (tramp-get-remote-stat vec) - (if (eq id-format 'integer) "%ue0" "/%U/") - (if (eq id-format 'integer) "%ge0" "/%G/")))) + (if (eq id-format 'integer) "%ue0" "//%U//") + (if (eq id-format 'integer) "%ge0" "//%G//")))) ;; This function should return "foo/" for directories and "bar" for ;; files.