emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 459bd56: Further fixes while testing tramp-crypt


From: Michael Albinus
Subject: master 459bd56: Further fixes while testing tramp-crypt
Date: Fri, 12 Jun 2020 14:17:11 -0400 (EDT)

branch: master
commit 459bd56f46af8cd7c29965600c46387282c3c93f
Author: Michael Albinus <michael.albinus@gmx.de>
Commit: Michael Albinus <michael.albinus@gmx.de>

    Further fixes while testing tramp-crypt
    
    * doc/misc/tramp.texi (External methods): Remove experimental note
    for rclone.
    (Keeping files encrypted): Mark file encryption as experimental.
    
    * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist):
    Use `tramp-handle-file-truename'.
    (tramp-adb-handle-file-truename): Remove.
    
    * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
    Add `file-writable-p'.
    (tramp-crypt-send-command): Return t if no error.
    (tramp-crypt-do-encrypt-or-decrypt-file-name)
    (tramp-crypt-do-encrypt-or-decrypt-file): Raise an error if it fails.
    (tramp-crypt-do-copy-or-rename-file): Flush file properties also
    when copying a directory.
    (tramp-crypt-handle-file-writable-p): New defun.
    (tramp-crypt-handle-insert-directory): Check for library
    `text-property-search'.
    
    * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-uid-gid):
    Rename from `tramp-gvfs-set-file-uid-gid'.
    
    * lisp/net/tramp-sh.el (tramp-sh-handle-file-truename):
    Use `tramp-handle-file-truename' as fallback.
    
    * lisp/net/tramp.el (tramp-handle-file-truename):
    Let-bind `tramp-crypt-enabled' to nil.
    (tramp-handle-write-region): Set also file ownership.
    
    * test/lisp/net/tramp-tests.el (tramp-test17-insert-directory):
    Skip if needed.
---
 doc/misc/tramp.texi          |   7 +--
 lisp/net/tramp-adb.el        | 100 +-----------------------------------
 lisp/net/tramp-crypt.el      | 120 ++++++++++++++++++++++++-------------------
 lisp/net/tramp-gvfs.el       |   2 +-
 lisp/net/tramp-sh.el         |  56 ++------------------
 lisp/net/tramp.el            |  25 ++++++---
 test/lisp/net/tramp-tests.el |   3 ++
 7 files changed, 97 insertions(+), 216 deletions(-)

diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 176d3a5..eb0bf74 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -1185,9 +1185,6 @@ for accessing the system storage, you shall prefer this.
 @ref{GVFS-based methods} for example, methods @option{gdrive} and
 @option{nextcloud}.
 
-@strong{Note}: The @option{rclone} method is experimental, don't use
-it in production systems!
-
 @end table
 
 
@@ -1732,6 +1729,7 @@ Convenience method to access vagrant boxes.  It is often 
used in
 multi-hop file names like
 
@file{@value{prefix}vagrant@value{postfixhop}box|sudo@value{postfixhop}box@value{postfix}/path/to/file},
 where @samp{box} is the name of the vagrant box.
+
 @end table
 
 
@@ -2655,6 +2653,9 @@ to direct all auto saves to that location.
 @section Protect remote files by encryption
 @cindex Encrypt remote directories
 
+@strong{Note}: File encryption in @value{tramp} is experimental, don't
+use it in production systems!
+
 Sometimes, it is desirable to protect files located on remote
 directories, like cloud storages.  In order to do this, you might
 instruct @value{tramp} to encrypt all files copied to a given remote
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index b4a080e..fb98805 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -136,7 +136,7 @@ It is used for TCP/IP devices."
     (file-selinux-context . tramp-handle-file-selinux-context)
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-adb-handle-file-system-info)
-    (file-truename . tramp-adb-handle-file-truename)
+    (file-truename . tramp-handle-file-truename)
     (file-writable-p . tramp-adb-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
@@ -227,104 +227,6 @@ ARGUMENTS to pass to the OPERATION."
                           (string-to-number (match-string 2))))
                (* 1024 (string-to-number (match-string 3)))))))))
 
-;; This is derived from `tramp-sh-handle-file-truename'.  Maybe the
-;; code could be shared?
-(defun tramp-adb-handle-file-truename (filename)
-  "Like `file-truename' for Tramp files."
-  ;; Preserve trailing "/".
-  (funcall
-   (if (directory-name-p filename) #'file-name-as-directory #'identity)
-   ;; Quote properly.
-   (funcall
-    (if (tramp-compat-file-name-quoted-p filename)
-       #'tramp-compat-file-name-quote #'identity)
-    (with-parsed-tramp-file-name
-       (tramp-compat-file-name-unquote (expand-file-name filename)) nil
-      (tramp-make-tramp-file-name
-       v
-       (with-tramp-file-property v localname "file-truename"
-        (let (result)                  ; result steps in reverse order
-          (tramp-message v 4 "Finding true name for `%s'" filename)
-          (let* ((steps (split-string localname "/" 'omit))
-                 (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)
-            (while (and steps (< numchase numchase-limit))
-              (setq thisstep (pop steps))
-              (tramp-message
-               v 5 "Check %s"
-               (string-join
-                (append '("") (reverse result) (list thisstep)) "/"))
-              (setq symlink-target
-                    (tramp-compat-file-attribute-type
-                     (file-attributes
-                      (tramp-make-tramp-file-name
-                       v
-                       (string-join
-                        (append
-                         '("") (reverse result) (list thisstep)) "/")))))
-              (cond ((string= "." thisstep)
-                     (tramp-message v 5 "Ignoring step `.'"))
-                    ((string= ".." thisstep)
-                     (tramp-message v 5 "Processing step `..'")
-                     (pop result))
-                    ((stringp symlink-target)
-                     ;; It's a symlink, follow it.
-                     (tramp-message v 5 "Follow symlink to %s" symlink-target)
-                     (setq numchase (1+ numchase))
-                     (when (file-name-absolute-p symlink-target)
-                       (setq result nil))
-                     ;; If the symlink was absolute, we'll get a string
-                     ;; like "/user@host:/some/target"; extract the
-                     ;; "/some/target" part from it.
-                     (when (tramp-tramp-file-p symlink-target)
-                       (unless (tramp-equal-remote filename symlink-target)
-                         (tramp-error
-                          v 'file-error
-                          "Symlink target `%s' on wrong host" symlink-target))
-                       (setq symlink-target localname))
-                     (setq steps
-                           (append (split-string symlink-target "/" 'omit)
-                                   steps)))
-                    (t
-                     ;; It's a file.
-                     (setq result (cons thisstep result)))))
-            (when (>= numchase numchase-limit)
-              (tramp-error
-               v 'file-error
-               "Maximum number (%d) of symlinks exceeded" numchase-limit))
-            (setq result (reverse result))
-            ;; Combine list to form string.
-            (setq result
-                  (if result
-                      (string-join (cons "" result) "/")
-                    "/"))
-            (when (and is-dir (or (string-empty-p result)
-                                  (not (string= (substring result -1) "/"))))
-              (setq result (concat result "/"))))
-
-          ;; Detect cycle.
-          (when (and (file-symlink-p filename)
-                     (string-equal result localname))
-            (tramp-error
-             v 'file-error
-             "Apparent cycle of symbolic links for %s" filename))
-          ;; If the resulting localname looks remote, we must quote it
-          ;; for security reasons.
-          (when (file-remote-p result)
-            (setq result (tramp-compat-file-name-quote result 'top)))
-          (tramp-message v 4 "True name of `%s' is `%s'" localname result)
-          result)))))))
-
 (defun tramp-adb-handle-file-attributes (filename &optional id-format)
   "Like `file-attributes' for Tramp files."
   (unless id-format (setq id-format 'integer))
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index 664f441..e63d836 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -24,7 +24,7 @@
 ;;; Commentary:
 
 ;; Access functions for crypted remote files.  It uses encfs to
-;; encrypt/ decrypt the files on a remote directory.  A remote
+;; encrypt / decrypt the files on a remote directory.  A remote
 ;; directory, which shall include crypted files, must be declared in
 ;; `tramp-crypt-directories' via command `tramp-crypt-add-directory'.
 ;; All files in that directory, including all subdirectories, are
@@ -189,8 +189,8 @@ If NAME doesn't belong to a crypted remote directory, retun 
nil."
     (file-selinux-context . ignore)
     (file-symlink-p . tramp-handle-file-symlink-p)
     (file-system-info . tramp-crypt-handle-file-system-info)
-    ;; (file-truename . tramp-crypt-handle-file-truename)
-    ;; (file-writable-p . ignore)
+    ;; `file-truename' performed by default handler.
+    (file-writable-p . tramp-crypt-handle-file-writable-p)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
     ;; `get-file-buffer' performed by default handler.
     (insert-directory . tramp-crypt-handle-insert-directory)
@@ -351,7 +351,7 @@ connection if a previous connection has died for some 
reason."
 
 (defun tramp-crypt-send-command (vec &rest args)
   "Send encfsctl command to connection VEC.
-ARGS are the arguments."
+ARGS are the arguments.  It returns t if ran successful, and nil otherwise."
   (tramp-crypt-maybe-open-connection vec)
   (with-current-buffer (tramp-get-connection-buffer vec)
     (erase-buffer))
@@ -380,11 +380,12 @@ ARGS are the arguments."
        ;; Save the password.
        (ignore-errors
          (and (functionp tramp-password-save-function)
-              (funcall tramp-password-save-function)))))))
+              (funcall tramp-password-save-function)))
+       t))))
 
 (defun tramp-crypt-do-encrypt-or-decrypt-file-name (op name)
-  "Return encrypted/ decrypted NAME if NAME belongs to a crypted directory.
-OP must be `encrypt' or `decrypt'.
+  "Return encrypted / decrypted NAME if NAME belongs to a crypted directory.
+OP must be `encrypt' or `decrypt'.  Raise an error if this fails.
 Otherwise, return NAME."
   (if-let ((tramp-crypt-enabled t)
           (dir (tramp-crypt-file-name-p name))
@@ -399,9 +400,12 @@ Otherwise, return NAME."
        (unless (string-equal localname "/")
          (with-tramp-file-property
              crypt-vec localname (concat (symbol-name op) "-file-name")
-           (tramp-crypt-send-command
-            crypt-vec (if (eq op 'encrypt) "encode" "decode")
-            (tramp-compat-temporary-file-directory) localname)
+           (unless (tramp-crypt-send-command
+                    crypt-vec (if (eq op 'encrypt) "encode" "decode")
+                    (tramp-compat-temporary-file-directory) localname)
+             (tramp-error
+              crypt-vec "%s of file name %s failed."
+              (if (eq op 'encrypt) "Encoding" "Decoding") name))
            (with-current-buffer (tramp-get-connection-buffer crypt-vec)
              (goto-char (point-min))
              (buffer-substring (point-min) (point-at-eol)))))))
@@ -419,9 +423,10 @@ Otherwise, return NAME."
   (tramp-crypt-do-encrypt-or-decrypt-file-name 'decrypt name))
 
 (defun tramp-crypt-do-encrypt-or-decrypt-file (op root infile outfile)
-  "Encrypt/ decrypt file INFILE to OUTFILE according to crypted directory ROOT.
+  "Encrypt / decrypt file INFILE to OUTFILE according to crypted directory 
ROOT.
 Both files must be local files.  OP must be `encrypt' or `decrypt'.
-If OP ist `decrypt', the basename of INFILE must be an encrypted file name."
+If OP ist `decrypt', the basename of INFILE must be an encrypted file name.
+Raise an error if this fails."
   (when-let ((tramp-crypt-enabled t)
             (dir (tramp-crypt-file-name-p root))
             (crypt-vec (tramp-crypt-dissect-file-name dir)))
@@ -429,10 +434,13 @@ If OP ist `decrypt', the basename of INFILE must be an 
encrypted file name."
           (if (eq op 'decrypt) 'binary coding-system-for-read))
          (coding-system-for-write
           (if (eq op 'encrypt) 'binary coding-system-for-write)))
-      (tramp-crypt-send-command
-       crypt-vec "cat" (and (eq op 'encrypt) "--reverse")
-       (file-name-directory infile)
-       (concat "/" (file-name-nondirectory infile)))
+      (unless (tramp-crypt-send-command
+              crypt-vec "cat" (and (eq op 'encrypt) "--reverse")
+              (file-name-directory infile)
+              (concat "/" (file-name-nondirectory infile)))
+       (tramp-error
+        crypt-vec "%s of file %s failed."
+        (if (eq op 'encrypt) "Encrypting" "Decrypting") infile))
       (with-current-buffer (tramp-get-connection-buffer crypt-vec)
        (write-region nil nil outfile)))))
 
@@ -520,16 +528,17 @@ absolute file names."
     (error "Unknown operation `%s', must be `copy' or `rename'" op))
 
   (setq filename (file-truename filename))
-  (if (file-directory-p filename)
-      (progn
-       (copy-directory filename newname keep-date t)
-       (when (eq op 'rename) (delete-directory filename 'recursive)))
-
-    (let ((t1 (tramp-crypt-file-name-p filename))
-         (t2 (tramp-crypt-file-name-p newname))
-         (encrypt-filename (tramp-crypt-encrypt-file-name filename))
-         (encrypt-newname (tramp-crypt-encrypt-file-name newname))
-         (msg-operation (if (eq op 'copy) "Copying" "Renaming")))
+  (let ((t1 (tramp-crypt-file-name-p filename))
+       (t2 (tramp-crypt-file-name-p newname))
+       (encrypt-filename (tramp-crypt-encrypt-file-name filename))
+       (encrypt-newname (tramp-crypt-encrypt-file-name newname))
+       (msg-operation (if (eq op 'copy) "Copying" "Renaming")))
+
+    (if (file-directory-p filename)
+       (progn
+         (copy-directory filename newname keep-date t)
+         (when (eq op 'rename)
+           (delete-directory filename 'recursive)))
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
@@ -581,15 +590,15 @@ absolute file names."
                  (rename-file filename tmpfile1 t))
                (tramp-crypt-encrypt-file t2 tmpfile1 tmpfile2)
                (rename-file tmpfile2 encrypt-newname ok-if-already-exists)))
-             (delete-directory tmpdir 'recursive)))
+             (delete-directory tmpdir 'recursive))))))
 
-         (when (and t1 (eq op 'rename))
-           (with-parsed-tramp-file-name filename v1
-             (tramp-flush-file-properties v1 v1-localname)))
+    (when (and t1 (eq op 'rename))
+      (with-parsed-tramp-file-name filename v1
+       (tramp-flush-file-properties v1 v1-localname)))
 
-         (when t2
-           (with-parsed-tramp-file-name newname v2
-             (tramp-flush-file-properties v2 v2-localname))))))))
+    (when t2
+      (with-parsed-tramp-file-name newname v2
+       (tramp-flush-file-properties v2 v2-localname)))))
 
 (defun tramp-crypt-handle-copy-file
   (filename newname &optional ok-if-already-exists keep-date
@@ -692,28 +701,35 @@ absolute file names."
    ;; #'file-system-info.
    'file-system-info (list (tramp-crypt-encrypt-file-name filename))))
 
+(defun tramp-crypt-handle-file-writable-p (filename)
+  "Like `file-writable-p' for Tramp files."
+  (let (tramp-crypt-enabled)
+    (file-writable-p (tramp-crypt-encrypt-file-name filename))))
+
 (defun tramp-crypt-handle-insert-directory
   (filename switches &optional wildcard full-directory-p)
   "Like `insert-directory' for Tramp files."
-  (let (tramp-crypt-enabled)
-    (tramp-handle-insert-directory
-     (tramp-crypt-encrypt-file-name filename)
-     switches wildcard full-directory-p)
-    (let* ((filename (file-name-as-directory filename))
-          (enc (tramp-crypt-encrypt-file-name filename))
-          match string)
-      (goto-char (point-min))
-      (while (setq match (text-property-search-forward 'dired-filename t t))
-       (setq string
-             (buffer-substring
-              (prop-match-beginning match) (prop-match-end match))
-             string (if (file-name-absolute-p string)
-                        (tramp-crypt-decrypt-file-name string)
-                      (substring
-                       (tramp-crypt-decrypt-file-name (concat enc string))
-                       (length filename))))
-       (delete-region (prop-match-beginning match) (prop-match-end match))
-       (insert (propertize string 'dired-filename t))))))
+  ;; This package has been added to Emacs 27.1.
+  (when (load "text-property-search" 'noerror 'nomessage)
+    (let (tramp-crypt-enabled)
+      (tramp-handle-insert-directory
+       (tramp-crypt-encrypt-file-name filename)
+       switches wildcard full-directory-p)
+      (let* ((filename (file-name-as-directory filename))
+            (enc (tramp-crypt-encrypt-file-name filename))
+            match string)
+       (goto-char (point-min))
+       (while (setq match (text-property-search-forward 'dired-filename t t))
+         (setq string
+               (buffer-substring
+                (prop-match-beginning match) (prop-match-end match))
+               string (if (file-name-absolute-p string)
+                          (tramp-crypt-decrypt-file-name string)
+                        (substring
+                         (tramp-crypt-decrypt-file-name (concat enc string))
+                         (length filename))))
+         (delete-region (prop-match-beginning match) (prop-match-end match))
+         (insert (propertize string 'dired-filename t)))))))
 
 (defun tramp-crypt-handle-make-directory (dir &optional parents)
   "Like `make-directory' for Tramp files."
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 704d65c..89e9b13 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -1589,7 +1589,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
               (current-time)
             time)))))
 
-(defun tramp-gvfs-set-file-uid-gid (filename &optional uid gid)
+(defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid)
   "Like `tramp-set-file-uid-gid' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (tramp-flush-file-properties v localname)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index a3ce436..bcbb724 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1153,59 +1153,9 @@ component is used as the target of the symlink."
                            (tramp-shell-quote-argument localname)))))
 
            ;; Do it yourself.
-           (t (let ((steps (split-string localname "/" 'omit))
-                    (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
-                   v 5 "Check %s"
-                   (string-join
-                    (append '("") (reverse result) (list thisstep)) "/"))
-                  (setq symlink-target
-                        (tramp-compat-file-attribute-type
-                         (file-attributes
-                          (tramp-make-tramp-file-name
-                           v
-                           (string-join
-                            (append
-                             '("") (reverse result) (list thisstep)) "/")
-                           'nohop))))
-                  (cond ((string= "." thisstep)
-                         (tramp-message v 5 "Ignoring step `.'"))
-                        ((string= ".." thisstep)
-                         (tramp-message v 5 "Processing step `..'")
-                         (pop result))
-                        ((stringp symlink-target)
-                         ;; It's a symlink, follow it.
-                         (tramp-message
-                          v 5 "Follow symlink to %s" symlink-target)
-                         (setq numchase (1+ numchase))
-                         (when (file-name-absolute-p symlink-target)
-                           (setq result nil))
-                         (setq steps
-                               (append
-                                (split-string symlink-target "/" 'omit)
-                                steps)))
-                        (t
-                         ;; It's a file.
-                         (setq result (cons thisstep result)))))
-                (when (>= numchase numchase-limit)
-                  (tramp-error
-                   v 'file-error
-                   "Maximum number (%d) of symlinks exceeded" numchase-limit))
-                (setq result (reverse result)
-                      ;; Combine list to form string.
-                      result
-                      (if result (string-join (cons "" result) "/") "/"))
-                (when (string-empty-p result) (setq result "/")))))
+           (t (setq
+               result
+               (tramp-file-local-name (tramp-handle-file-truename filename)))))
 
           ;; Detect cycle.
           (when (and (file-symlink-p filename)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index f1db6a7b..b045e41 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -3381,6 +3381,8 @@ User is always nil."
          ;; something is wrong; otherwise they might think that Emacs
          ;; is hung.  Of course, correctness has to come first.
          (numchase-limit 20)
+         ;; Unquoting could enable encryption.
+         tramp-crypt-enabled
          symlink-target)
       (with-parsed-tramp-file-name result v1
        ;; We cache only the localname.
@@ -3900,7 +3902,11 @@ of."
 
     (let ((tmpfile (tramp-compat-make-temp-file filename))
          (modes (tramp-default-file-modes
-                 filename (and (eq mustbenew 'excl) 'nofollow))))
+                 filename (and (eq mustbenew 'excl) 'nofollow)))
+         (uid (tramp-compat-file-attribute-user-id
+               (file-attributes filename 'integer)))
+         (gid (tramp-compat-file-attribute-group-id
+               (file-attributes filename 'integer))))
       (when (and append (file-exists-p filename))
        (copy-file filename tmpfile 'ok))
       ;; The permissions of the temporary file should be set.  If
@@ -3919,15 +3925,18 @@ of."
        (error
         (delete-file tmpfile)
         (tramp-error
-         v 'file-error "Couldn't write region to `%s'" filename))))
+         v 'file-error "Couldn't write region to `%s'" filename)))
 
-    (tramp-flush-file-properties v localname)
+      (tramp-flush-file-properties v localname)
 
-    ;; Set file modification time.
-    (when (or (eq visit t) (stringp visit))
-      (set-visited-file-modtime
-       (tramp-compat-file-attribute-modification-time
-       (file-attributes filename))))
+      ;; Set file modification time.
+      (when (or (eq visit t) (stringp visit))
+       (set-visited-file-modtime
+        (tramp-compat-file-attribute-modification-time
+         (file-attributes filename))))
+
+      ;; Set the ownership.
+      (tramp-set-file-uid-gid filename uid gid))
 
     ;; The end.
     (when (and (null noninteractive)
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 578da41..9667b34 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -2925,6 +2925,9 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
   ;; (this is performed by `dired').  If FULL is nil, it shows just
   ;; one file.  So we refrain from testing.
   (skip-unless (not (tramp--test-ange-ftp-p)))
+  ;; `insert-directory' of crypted remote directories works only since
+  ;; Emacs 27.1.
+  (skip-unless (or (not (tramp--test-crypt-p)) (tramp--test-emacs27-p)))
 
   (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
     (let* ((tmp-name1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]