Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
+(defconst tramp-stat-file-attributes-with-selinux
+ (format
+ (concat
+ "(%%s -c"
+ " '((%s%%%%N%s) %%%%h (%s%%%%U%s . %%%%u) (%s%%%%G%s . %%%%g)"
+ " %%%%X %%%%Y %%%%Z %%%%s %s%%%%A%s t %%%%i -1 %s%%%%C%s)'"
+ " \"$1\" %%n || echo nil) |"
+ " sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'")
+ tramp-stat-marker tramp-stat-marker ; %%N
+ tramp-stat-marker tramp-stat-marker ; %%U
+ tramp-stat-marker tramp-stat-marker ; %%G
+ tramp-stat-marker tramp-stat-marker ; %%A
+ tramp-stat-marker tramp-stat-marker ; %%C
+ tramp-stat-quoted-marker)
+ "Shell function to produce output suitable for use with `file-attributes'
+on the remote file system, including SELinux context.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
+
(defconst tramp-perl-directory-files-and-attributes
"%p -e '
chdir($ARGV[0]) or printf(\"\\\"Cannot change to $ARGV[0]: $''!''\\\"\\n\"), exit();
Format specifiers are replaced by `tramp-expand-script', percent
characters need to be doubled.")
+(defconst tramp-stat-directory-files-and-attributes-with-selinux
+ (format
+ (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. `tramp-sh--quoting-style-options' do
+ ;; not work for file names with spaces piped to "xargs".
+ ;; Apostrophes in the stat output are masked as
+ ;; `tramp-stat-marker', in order to make a proper shell escape of
+ ;; them in file names.
+ "cd \"$1\" && echo \"(\"; (%%l -a | tr '\\n\\r' '\\000\\000' |"
+ " xargs -0 %%s -c"
+ " '(%s%%%%n%s (%s%%%%N%s) %%%%h (%s%%%%U%s . %%%%u) (%s%%%%G%s . %%%%g) %%%%X %%%%Y %%%%Z %%%%s %s%%%%A%s t %%%%i -1 %s%%%%C%s)'"
+ " -- %%n | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"")
+ tramp-stat-marker tramp-stat-marker ; %n
+ tramp-stat-marker tramp-stat-marker ; %N
+ tramp-stat-marker tramp-stat-marker ; %U
+ tramp-stat-marker tramp-stat-marker ; %G
+ tramp-stat-marker tramp-stat-marker ; %A
+ tramp-stat-marker tramp-stat-marker ; %C
+ tramp-stat-quoted-marker)
+ "Shell function implementing `directory-files-and-attributes' as Lisp
+`read'able output, including SELinux context.
+Format specifiers are replaced by `tramp-expand-script', percent
+characters need to be doubled.")
+
(defconst tramp-perl-id
"%p -e '
use strict;
(let (symlinkp dirp
res-inode res-filemodes res-numlinks
res-uid-string res-gid-string res-uid-integer res-gid-integer
- res-size res-symlink-target)
+ res-size res-symlink-target res-context)
(tramp-message vec 5 "file attributes with ls: %s" localname)
- ;; We cannot send all three commands combined, it could exceed
- ;; NAME_MAX or PATH_MAX. Happened on macOS, for example.
+ ;; We cannot send both commands combined, it could exceed NAME_MAX
+ ;; or PATH_MAX. Happened on macOS, for example.
(when (tramp-send-command-and-check
vec
(format "cd %s && (%s %s || %s -h %s)"
(file-name-nondirectory localname)))))
(tramp-send-command
vec
- (format "%s -ild %s %s; %s -lnd %s %s"
+ (format "%s -ild %s %s; %s -lnd%s %s %s"
(tramp-get-ls-command vec)
;; On systems which have no quoting style, file names
;; with special characters could fail.
(tramp-sh--quoting-style-options vec)
(tramp-shell-quote-argument localname)
(tramp-get-ls-command vec)
+ (if (tramp-remote-selinux-p vec) "Z" "")
;; On systems which have no quoting style, file names
;; with special characters could fail.
(tramp-sh--quoting-style-options vec)
(setq res-uid-integer tramp-unknown-id-integer))
(unless (numberp res-gid-integer)
(setq res-gid-integer tramp-unknown-id-integer))
+ ;; ... SELinux context
+ (when (tramp-remote-selinux-p vec)
+ (setq res-context (read (current-buffer))
+ res-context (symbol-name res-context)))
;; Return data gathered.
(list
;; 10. Inode number.
res-inode
;; 11. Device number. Will be replaced by a virtual device number.
- -1))))))
+ -1
+ ;; 12. SELinux context. Will be extracted in
+ ;; `tramp-convert-file-attributes'.
+ res-context))))))
(defun tramp-do-file-attributes-with-perl (vec localname)
"Implement `file-attributes' for Tramp files using a Perl script."
(defun tramp-do-file-attributes-with-stat (vec localname)
"Implement `file-attributes' for Tramp files using stat(1) command."
(tramp-message vec 5 "file attributes with stat: %s" localname)
- (tramp-maybe-send-script
- vec tramp-stat-file-attributes "tramp_stat_file_attributes")
- (tramp-send-command-and-read
- vec (format "tramp_stat_file_attributes %s"
- (tramp-shell-quote-argument localname))))
+ (cond
+ ((tramp-remote-selinux-p vec)
+ (tramp-maybe-send-script
+ vec tramp-stat-file-attributes-with-selinux
+ "tramp_stat_file_attributes_with_selinux")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_file_attributes_with_selinux %s"
+ (tramp-shell-quote-argument localname))))
+ (t
+ (tramp-maybe-send-script
+ vec tramp-stat-file-attributes "tramp_stat_file_attributes")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_file_attributes %s"
+ (tramp-shell-quote-argument localname))))))
(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
"Like `set-visited-file-modtime' for Tramp files."
(tramp-shell-quote-argument localname))))))))
(defun tramp-remote-selinux-p (vec)
- "Check, whether SELINUX is enabled on the remote host."
+ "Check, whether SELinux is enabled on the remote host."
(with-tramp-connection-property (tramp-get-process vec) "selinux-p"
(tramp-send-command-and-check vec "selinuxenabled")))
(defun tramp-do-directory-files-and-attributes-with-stat (vec localname)
"Implement `directory-files-and-attributes' for Tramp files with stat(1) command."
(tramp-message vec 5 "directory-files-and-attributes with stat: %s" localname)
- (tramp-maybe-send-script
- vec tramp-stat-directory-files-and-attributes
- "tramp_stat_directory_files_and_attributes")
- (tramp-send-command-and-read
- vec (format "tramp_stat_directory_files_and_attributes %s"
- (tramp-shell-quote-argument localname))))
+ (cond
+ ((tramp-remote-selinux-p vec)
+ (tramp-maybe-send-script
+ vec tramp-stat-directory-files-and-attributes-with-selinux
+ "tramp_stat_directory_files_and_attributes_with_selinux")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_directory_files_and_attributes_with_selinux %s"
+ (tramp-shell-quote-argument localname))))
+ (t
+ (tramp-maybe-send-script
+ vec tramp-stat-directory-files-and-attributes
+ "tramp_stat_directory_files_and_attributes")
+ (tramp-send-command-and-read
+ vec (format "tramp_stat_directory_files_and_attributes %s"
+ (tramp-shell-quote-argument localname))))))
;; This function should return "foo/" for directories and "bar" for
;; files.
KEEP-DATE means to make sure that NEWNAME has the same timestamp
as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
the uid and gid if both files are on the same host.
-PRESERVE-EXTENDED-ATTRIBUTES activates selinux and acl commands.
+PRESERVE-EXTENDED-ATTRIBUTES activates SELinux and ACL commands.
This function is invoked by `tramp-sh-handle-copy-file' and
`tramp-sh-handle-rename-file'. It is an error if OP is neither
KEEP-DATE means to make sure that NEWNAME has the same timestamp
as FILENAME. PRESERVE-UID-GID, when non-nil, instructs to keep
the uid and gid if both files are on the same host.
-PRESERVE-EXTENDED-ATTRIBUTES activates selinux and acl commands.
+PRESERVE-EXTENDED-ATTRIBUTES activates SELinux and ACL commands.
This function is invoked by `tramp-sudoedit-handle-copy-file' and
`tramp-sudoedit-handle-rename-file'. It is an error if OP is
"stat format string to produce output suitable for use with
`file-attributes' on the remote file system.")
+(defconst tramp-sudoedit-file-attributes-with-selinux
+ (format
+ ;; Apostrophes in the stat output are masked as
+ ;; `tramp-stat-marker', in order to make a proper shell escape of
+ ;; them in file names. They are replaced in
+ ;; `tramp-sudoedit-send-command-and-read'.
+ (concat "((%s%%N%s) %%h (%s%%U%s . %%u) (%s%%G%s . %%g)"
+ " %%X %%Y %%Z %%s %s%%A%s t %%i -1 %s%%C%s)")
+ tramp-stat-marker tramp-stat-marker ; %%N
+ tramp-stat-marker tramp-stat-marker ; %%U
+ tramp-stat-marker tramp-stat-marker ; %%G
+ tramp-stat-marker tramp-stat-marker ; %%A
+ tramp-stat-marker tramp-stat-marker) ; %%C
+ "stat format string to produce output suitable for use with
+`file-attributes' on the remote file system, including SELinux context.")
+
(defun tramp-sudoedit-handle-file-attributes (filename &optional id-format)
"Like `file-attributes' for Tramp files."
;; The result is cached in `tramp-convert-file-attributes'.
(with-parsed-tramp-file-name (expand-file-name filename) nil
(tramp-convert-file-attributes v localname id-format
- (tramp-sudoedit-send-command-and-read
- v "env" "QUOTING_STYLE=locale" "stat" "-c"
- tramp-sudoedit-file-attributes (file-name-unquote localname)))))
+ (cond
+ ((tramp-sudoedit-remote-selinux-p v)
+ (tramp-sudoedit-send-command-and-read
+ v "env" "QUOTING_STYLE=locale" "stat" "-c"
+ tramp-sudoedit-file-attributes-with-selinux
+ (file-name-unquote localname)))
+ (t
+ (tramp-sudoedit-send-command-and-read
+ v "env" "QUOTING_STYLE=locale" "stat" "-c"
+ tramp-sudoedit-file-attributes (file-name-unquote localname)))))))
(defun tramp-sudoedit-handle-file-executable-p (filename)
"Like `file-executable-p' for Tramp files."
v 'file-error "Error while changing file's mode %s" filename)))))
(defun tramp-sudoedit-remote-selinux-p (vec)
- "Check, whether SELINUX is enabled on the remote host."
+ "Check, whether SELinux is enabled on the remote host."
(with-tramp-connection-property (tramp-get-process vec) "selinux-p"
(zerop (tramp-call-process vec "selinuxenabled"))))