aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/eshell
diff options
context:
space:
mode:
authorJim Porter2023-05-01 09:49:00 -0700
committerJim Porter2023-05-02 21:28:34 -0700
commit40d66095635ead025b33dc693a19b463f70eb9ce (patch)
tree75459d0d63878ddda41018cba4bc9dad0b6136bc /lisp/eshell
parentfa33a14ebe56aa1726df9c8ad93106966c5b6eae (diff)
downloademacs-40d66095635ead025b33dc693a19b463f70eb9ce.tar.gz
emacs-40d66095635ead025b33dc693a19b463f70eb9ce.zip
Use connection-aware functions when getting the UID/GID in Eshell
This means, for example, that when using Tramp to sudo in Eshell, "rm" queries the user before deleting anything (bug#63221). * lisp/eshell/esh-util.el (eshell-user-login-name): New function... * lisp/eshell/em-unix.el (eshell/whoami): ... use it. * lisp/eshell/em-ls.el (eshell-ls-applicable): Use 'file-user-uid' and 'eshell-user-login-name'. (eshell-ls-decorated-name): Use 'file-user-uid'. * lisp/eshell/em-pred.el (eshell-predicate-alist): Use 'file-user-uid' and 'file-group-gid'. * lisp/eshell/em-unix.el (eshell-interactive-query): New widget... (eshell-rm-interactive-query, eshell-mv-interactive-query) (eshell-cp-interactive-query, eshell-ln-interactive-query): ... use it. (eshell-interactive-query-p): New function... (eshell/rm, eshell/mv, eshell/cp, eshell/ln): ... use it. * lisp/simple.el (file-group-gid): New function. * lisp/net/ange-ftp.el (ange-ftp-file-group-gid): New function... (file-group-gid): ... use it. * lisp/net/tramp.el (tramp-handle-file-group-gid): * lisp/net/tramp-archive.el (tramp-archive-handle-file-group-gid): New functions. * lisp/net/tramp.el (tramp-file-name-for-operation): Add 'file-group-gid'. * lisp/net/tramp-adb.el (tramp-adb-file-name-handler-alist): * lisp/net/tramp-archive.el (tramp-archive-file-name-handler-alist): * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist): * lisp/net/tramp-gvfs.el (tramp-gvfs-file-name-handler-alist): * lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist): * lisp/net/tramp-sh.el (tramp-sh-file-name-handler-alist): * lisp/net/tramp-smb.el (tramp-smb-file-name-handler-alist): * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist): Add 'file-group-gid' mapping. * test/lisp/net/tramp-tests.el (tramp-test44-file-user-group-ids): * test/lisp/net/tramp-archive-tests.el (tramp-archive-test44-file-user-group-ids): Add tests for 'file-group-gid'. * doc/lispref/files.texi (Magic File Names): Mention 'file-group-gid'. * doc/lispref/os.texi (User Identification): Document 'file-group-gid', and move 'group-real-gid' to match the order of 'user-real-uid'. * etc/NEWS: Announce 'file-group-gid'.
Diffstat (limited to 'lisp/eshell')
-rw-r--r--lisp/eshell/em-ls.el6
-rw-r--r--lisp/eshell/em-pred.el4
-rw-r--r--lisp/eshell/em-unix.el70
-rw-r--r--lisp/eshell/esh-util.el5
4 files changed, 63 insertions, 22 deletions
diff --git a/lisp/eshell/em-ls.el b/lisp/eshell/em-ls.el
index 56c5f262789..9b53bf29559 100644
--- a/lisp/eshell/em-ls.el
+++ b/lisp/eshell/em-ls.el
@@ -199,9 +199,9 @@ calling FUNC with FILE as an argument."
199 `(let ((owner (file-attribute-user-id ,attrs)) 199 `(let ((owner (file-attribute-user-id ,attrs))
200 (modes (file-attribute-modes ,attrs))) 200 (modes (file-attribute-modes ,attrs)))
201 (cond ((cond ((numberp owner) 201 (cond ((cond ((numberp owner)
202 (= owner (user-uid))) 202 (= owner (file-user-uid)))
203 ((stringp owner) 203 ((stringp owner)
204 (or (string-equal owner (user-login-name)) 204 (or (string-equal owner (eshell-user-login-name))
205 (member owner (eshell-current-ange-uids))))) 205 (member owner (eshell-current-ange-uids)))))
206 ;; The user owns this file. 206 ;; The user owns this file.
207 (not (eq (aref modes ,index) ?-))) 207 (not (eq (aref modes ,index) ?-)))
@@ -919,7 +919,7 @@ to use, and each member of which is the width of that column
919 ((not (eshell-ls-filetype-p (cdr file) ?-)) 919 ((not (eshell-ls-filetype-p (cdr file) ?-))
920 'eshell-ls-special) 920 'eshell-ls-special)
921 921
922 ((and (/= (user-uid) 0) ; root can execute anything 922 ((and (/= (file-user-uid) 0) ; root can execute anything
923 (eshell-ls-applicable (cdr file) 3 923 (eshell-ls-applicable (cdr file) 3
924 'file-executable-p (car file))) 924 'file-executable-p (car file)))
925 'eshell-ls-executable) 925 'eshell-ls-executable)
diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el
index 2ccca092b86..bfb0dad60ef 100644
--- a/lisp/eshell/em-pred.el
+++ b/lisp/eshell/em-pred.el
@@ -87,11 +87,11 @@ ordinary strings."
87 (?U . (lambda (file) ; owned by effective uid 87 (?U . (lambda (file) ; owned by effective uid
88 (if (file-exists-p file) 88 (if (file-exists-p file)
89 (= (file-attribute-user-id (file-attributes file)) 89 (= (file-attribute-user-id (file-attributes file))
90 (user-uid))))) 90 (file-user-uid)))))
91 (?G . (lambda (file) ; owned by effective gid 91 (?G . (lambda (file) ; owned by effective gid
92 (if (file-exists-p file) 92 (if (file-exists-p file)
93 (= (file-attribute-group-id (file-attributes file)) 93 (= (file-attribute-group-id (file-attributes file))
94 (group-gid))))) 94 (file-group-gid)))))
95 (?* . (lambda (file) 95 (?* . (lambda (file)
96 (and (file-regular-p file) 96 (and (file-regular-p file)
97 (not (file-symlink-p file)) 97 (not (file-symlink-p file))
diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el
index a792493e071..b7ef0f0c40c 100644
--- a/lisp/eshell/em-unix.el
+++ b/lisp/eshell/em-unix.el
@@ -91,14 +91,29 @@ Otherwise, `rmdir' is required."
91 :type 'boolean 91 :type 'boolean
92 :group 'eshell-unix) 92 :group 'eshell-unix)
93 93
94(defcustom eshell-rm-interactive-query (= (user-uid) 0) 94(define-widget 'eshell-interactive-query 'radio
95 "If non-nil, `rm' will query before removing anything." 95 "When to interatively query the user about a particular operation.
96 :type 'boolean 96If t, always query. If nil, never query. If `root', query when
97the user is logged in as root (including when `default-directory'
98is remote with a root user)."
99 :args '((const :tag "Never" nil)
100 (const :tag "Always" t)
101 (const :tag "When root" root)))
102
103(defcustom eshell-rm-interactive-query 'root
104 "When `rm' should query before removing anything.
105If t, always query. If nil, never query. If `root', query when
106the user is logged in as root (including when `default-directory'
107is remote with a root user)."
108 :type 'eshell-interactive-query
97 :group 'eshell-unix) 109 :group 'eshell-unix)
98 110
99(defcustom eshell-mv-interactive-query (= (user-uid) 0) 111(defcustom eshell-mv-interactive-query 'root
100 "If non-nil, `mv' will query before overwriting anything." 112 "When `mv' should query before overwriting anything.
101 :type 'boolean 113If t, always query. If nil, never query. If `root', query when
114the user is logged in as root (including when `default-directory'
115is remote with a root user)."
116 :type 'eshell-interactive-query
102 :group 'eshell-unix) 117 :group 'eshell-unix)
103 118
104(defcustom eshell-mv-overwrite-files t 119(defcustom eshell-mv-overwrite-files t
@@ -106,9 +121,12 @@ Otherwise, `rmdir' is required."
106 :type 'boolean 121 :type 'boolean
107 :group 'eshell-unix) 122 :group 'eshell-unix)
108 123
109(defcustom eshell-cp-interactive-query (= (user-uid) 0) 124(defcustom eshell-cp-interactive-query 'root
110 "If non-nil, `cp' will query before overwriting anything." 125 "When `cp' should query before overwriting anything.
111 :type 'boolean 126If t, always query. If nil, never query. If `root', query when
127the user is logged in as root (including when `default-directory'
128is remote with a root user)."
129 :type 'eshell-interactive-query
112 :group 'eshell-unix) 130 :group 'eshell-unix)
113 131
114(defcustom eshell-cp-overwrite-files t 132(defcustom eshell-cp-overwrite-files t
@@ -116,9 +134,12 @@ Otherwise, `rmdir' is required."
116 :type 'boolean 134 :type 'boolean
117 :group 'eshell-unix) 135 :group 'eshell-unix)
118 136
119(defcustom eshell-ln-interactive-query (= (user-uid) 0) 137(defcustom eshell-ln-interactive-query 'root
120 "If non-nil, `ln' will query before overwriting anything." 138 "When `ln' should query before overwriting anything.
121 :type 'boolean 139If t, always query. If nil, never query. If `root', query when
140the user is logged in as root (including when `default-directory'
141is remote with a root user)."
142 :type 'eshell-interactive-query
122 :group 'eshell-unix) 143 :group 'eshell-unix)
123 144
124(defcustom eshell-ln-overwrite-files nil 145(defcustom eshell-ln-overwrite-files nil
@@ -159,6 +180,17 @@ Otherwise, Emacs will attempt to use rsh to invoke du on the remote machine."
159(defvar em-recursive) 180(defvar em-recursive)
160(defvar em-verbose) 181(defvar em-verbose)
161 182
183(defun eshell-interactive-query-p (value)
184 "Return non-nil if a command should query the user according to VALUE.
185If VALUE is nil, return nil (never query). If `root', return
186non-nil if the user is logged in as root (including when
187`default-directory' is remote with a root user; see
188`file-user-uid'). If VALUE is any other non-nil value, return
189non-nil (always query)."
190 (if (eq value 'root)
191 (= (file-user-uid) 0)
192 value))
193
162(defun eshell/man (&rest args) 194(defun eshell/man (&rest args)
163 "Invoke man, flattening the arguments appropriately." 195 "Invoke man, flattening the arguments appropriately."
164 (funcall 'man (apply 'eshell-flatten-and-stringify args))) 196 (funcall 'man (apply 'eshell-flatten-and-stringify args)))
@@ -249,7 +281,8 @@ argument."
249 :usage "[OPTION]... FILE... 281 :usage "[OPTION]... FILE...
250Remove (unlink) the FILE(s).") 282Remove (unlink) the FILE(s).")
251 (unless em-interactive 283 (unless em-interactive
252 (setq em-interactive eshell-rm-interactive-query)) 284 (setq em-interactive (eshell-interactive-query-p
285 eshell-rm-interactive-query)))
253 (if (and force-removal em-interactive) 286 (if (and force-removal em-interactive)
254 (setq em-interactive nil)) 287 (setq em-interactive nil))
255 (while args 288 (while args
@@ -523,7 +556,8 @@ Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.
523[OPTION] DIRECTORY...") 556[OPTION] DIRECTORY...")
524 (let ((no-dereference t)) 557 (let ((no-dereference t))
525 (eshell-mvcpln-template "mv" "moving" 'rename-file 558 (eshell-mvcpln-template "mv" "moving" 'rename-file
526 eshell-mv-interactive-query 559 (eshell-interactive-query-p
560 eshell-mv-interactive-query)
527 eshell-mv-overwrite-files)))) 561 eshell-mv-overwrite-files))))
528 562
529(put 'eshell/mv 'eshell-no-numeric-conversions t) 563(put 'eshell/mv 'eshell-no-numeric-conversions t)
@@ -561,7 +595,8 @@ Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.")
561 (if archive 595 (if archive
562 (setq preserve t no-dereference t em-recursive t)) 596 (setq preserve t no-dereference t em-recursive t))
563 (eshell-mvcpln-template "cp" "copying" 'copy-file 597 (eshell-mvcpln-template "cp" "copying" 'copy-file
564 eshell-cp-interactive-query 598 (eshell-interactive-query-p
599 eshell-cp-interactive-query)
565 eshell-cp-overwrite-files preserve))) 600 eshell-cp-overwrite-files preserve)))
566 601
567(put 'eshell/cp 'eshell-no-numeric-conversions t) 602(put 'eshell/cp 'eshell-no-numeric-conversions t)
@@ -594,7 +629,8 @@ with `--symbolic'. When creating hard links, each TARGET must exist.")
594 (if symbolic 629 (if symbolic
595 'make-symbolic-link 630 'make-symbolic-link
596 'add-name-to-file) 631 'add-name-to-file)
597 eshell-ln-interactive-query 632 (eshell-interactive-query-p
633 eshell-ln-interactive-query)
598 eshell-ln-overwrite-files)))) 634 eshell-ln-overwrite-files))))
599 635
600(put 'eshell/ln 'eshell-no-numeric-conversions t) 636(put 'eshell/ln 'eshell-no-numeric-conversions t)
@@ -960,7 +996,7 @@ Show wall-clock time elapsed during execution of COMMAND.")
960 996
961(defun eshell/whoami (&rest _args) 997(defun eshell/whoami (&rest _args)
962 "Make \"whoami\" Tramp aware." 998 "Make \"whoami\" Tramp aware."
963 (or (file-remote-p default-directory 'user) (user-login-name))) 999 (eshell-user-login-name))
964 1000
965(defvar eshell-diff-window-config nil) 1001(defvar eshell-diff-window-config nil)
966 1002
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index c0685757789..3608c78ba2b 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -502,6 +502,11 @@ list."
502 (sit-for 0) 502 (sit-for 0)
503 (error nil))) 503 (error nil)))
504 504
505(defun eshell-user-login-name ()
506 "Return the connection-aware value of the user's login name.
507See also `user-login-name'."
508 (or (file-remote-p default-directory 'user) (user-login-name)))
509
505(defun eshell-read-passwd-file (file) 510(defun eshell-read-passwd-file (file)
506 "Return an alist correlating gids to group names in FILE." 511 "Return an alist correlating gids to group names in FILE."
507 (let (names) 512 (let (names)