aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2024-02-26 14:13:14 +0800
committerPo Lu2024-02-26 14:13:14 +0800
commitbabe6a5e948985f961ffd36f64323950abd98b7f (patch)
tree02190d786244ef4da6f962f54a0625d63426e2f7
parentc6f2add964ce1ac69ba6705bc869ee2f447da3cb (diff)
downloademacs-babe6a5e948985f961ffd36f64323950abd98b7f.tar.gz
emacs-babe6a5e948985f961ffd36f64323950abd98b7f.zip
Introduce a new TRAMP method `androidsu'
* doc/misc/tramp.texi (Quick Start Guide): Document the new method. * etc/NEWS (Tramp): Announce new method. * lisp/net/tramp-adb.el (tramp-adb-handle-file-attributes) (tramp-adb-handle-directory-files-and-attributes) (tramp-adb-handle-file-name-all-completions): Properly print ls's exit status in the presence of a pipe. (tramp-adb-handle-copy-file): If the androidsu backend is in use, call cp rather than adb push. (tramp-adb-send-command): Disable ADB-specific code under androidsu. (tramp-adb-send-command-and-check): New argument COMMAND-AUGMENTED-P. * lisp/net/tramp-androidsu.el (tramp, tramp-adb, tramp-sh) (tramp-androidsu-method, add-to-list) (tramp-androidsu-maybe-open-connection) (tramp-androidsu-generate-wrapper) (tramp-androidsu-handle-access-file) (tramp-androidsu-handle-add-name-to-file) (tramp-androidsu-handle-copy-directory) (tramp-androidsu-adb-handle-copy-file) (tramp-androidsu-adb-handle-delete-directory) (tramp-androidsu-adb-handle-delete-file) (tramp-androidsu-handle-directory-file-name) (tramp-androidsu-handle-directory-files) (tramp-androidsu-adb-handle-directory-files-and-attributes) (tramp-androidsu-handle-dired-uncache) (tramp-androidsu-adb-handle-exec-path) (tramp-androidsu-handle-expand-file-name) (tramp-androidsu-handle-file-accessible-directory-p) (tramp-androidsu-adb-handle-file-attributes) (tramp-androidsu-handle-file-directory-p) (tramp-androidsu-handle-file-equal-p) (tramp-androidsu-adb-handle-file-executable-p) (tramp-androidsu-adb-handle-file-exists-p) (tramp-androidsu-handle-file-group-gid) (tramp-androidsu-handle-file-in-directory-p) (tramp-androidsu-sh-handle-file-local-copy) (tramp-androidsu-handle-file-locked-p) (tramp-androidsu-handle-file-modes) (tramp-androidsu-adb-handle-file-name-all-completions) (tramp-androidsu-handle-file-name-as-directory) (tramp-androidsu-handle-file-name-case-insensitive-p) (tramp-androidsu-handle-file-name-completion) (tramp-androidsu-handle-file-name-directory) (tramp-androidsu-handle-file-name-nondirectory) (tramp-androidsu-handle-file-newer-than-file-p) (tramp-androidsu-handle-file-notify-add-watch) (tramp-androidsu-handle-file-notify-rm-watch) (tramp-androidsu-handle-file-notify-valid-p) (tramp-androidsu-adb-handle-file-readable-p) (tramp-androidsu-handle-file-regular-p) (tramp-androidsu-handle-file-remote-p) (tramp-androidsu-handle-file-selinux-context) (tramp-androidsu-handle-file-symlink-p) (tramp-androidsu-adb-handle-file-system-info) (tramp-androidsu-handle-file-truename) (tramp-androidsu-handle-file-user-uid) (tramp-androidsu-adb-handle-file-writable-p) (tramp-androidsu-handle-find-backup-file-name) (tramp-androidsu-handle-insert-directory) (tramp-androidsu-handle-insert-file-contents) (tramp-androidsu-handle-list-system-processes) (tramp-androidsu-handle-load, tramp-androidsu-handle-lock-file) (tramp-androidsu-handle-make-auto-save-file-name) (tramp-androidsu-adb-handle-make-directory) (tramp-androidsu-handle-make-lock-file-name) (tramp-androidsu-handle-make-nearby-temp-file) (tramp-androidsu-adb-handle-make-process) (tramp-androidsu-sh-handle-make-symbolic-link) (tramp-androidsu-handle-memory-info) (tramp-androidsu-handle-process-attributes) (tramp-androidsu-adb-handle-process-file) (tramp-androidsu-adb-handle-rename-file) (tramp-androidsu-adb-handle-set-file-modes) (tramp-androidsu-adb-handle-set-file-times) (tramp-androidsu-handle-set-visited-file-modtime) (tramp-androidsu-handle-shell-command) (tramp-androidsu-handle-start-file-process) (tramp-androidsu-handle-substitute-in-file-name) (tramp-androidsu-handle-temporary-file-directory) (tramp-androidsu-adb-handle-get-remote-gid) (tramp-androidsu-adb-handle-get-remote-groups) (tramp-androidsu-adb-handle-get-remote-uid) (tramp-androidsu-handle-unlock-file) (tramp-androidsu-handle-verify-visited-file-modtime) (tramp-androidsu-handle-write-region) (tramp-androidsu-file-name-handler-alist) (tramp-androidsu-file-name-p, tramp-androidsu-file-name-handler) (tramp-register-foreign-file-name-handler) (tramp-adb-connection-local-default-ps-profile, shell) (tramp-unload-hook, tramp-androidsu): New file.
-rw-r--r--doc/misc/tramp.texi7
-rw-r--r--etc/NEWS6
-rw-r--r--lisp/net/tramp-adb.el54
-rw-r--r--lisp/net/tramp-androidsu.el537
4 files changed, 589 insertions, 15 deletions
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 6d4654f1a8a..09b875ad3fa 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -523,6 +523,8 @@ is used as the group to change to. The default host name is the same.
523@cindex @option{sudo} method 523@cindex @option{sudo} method
524@cindex method @option{doas} 524@cindex method @option{doas}
525@cindex @option{doas} method 525@cindex @option{doas} method
526@cindex method @option{androidsu}
527@cindex @option{androidsu} method
526 528
527If the @option{su}, @option{sudo} or @option{doas} option should be 529If the @option{su}, @option{sudo} or @option{doas} option should be
528performed on another host, it can be combined with a leading 530performed on another host, it can be combined with a leading
@@ -533,6 +535,11 @@ a simple case, the syntax looks like
533@file{@trampfn{ssh@value{postfixhop}user@@host|sudo,,/path/to/file}}. 535@file{@trampfn{ssh@value{postfixhop}user@@host|sudo,,/path/to/file}}.
534@xref{Ad-hoc multi-hops}. 536@xref{Ad-hoc multi-hops}.
535 537
538The @option{su} method and other shell-based methods conflict with
539non-standard @command{su} implementations popular among Android users
540and the restricted command-line utilities distributed with that system.
541The @option{androidsu} method enables accessing files through
542@command{su} on such systems, but multi-hops are not supported.
536 543
537@anchor{Quick Start Guide sudoedit method} 544@anchor{Quick Start Guide sudoedit method}
538@section Using @command{sudoedit} 545@section Using @command{sudoedit}
diff --git a/etc/NEWS b/etc/NEWS
index 6d444daf152..b4a1c887f2e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -903,6 +903,12 @@ mode line. 'header' will display in the header line;
903** Tramp 903** Tramp
904 904
905+++ 905+++
906*** New connection method "androidsu".
907This provides access to system files with elevated privileges granted by
908the idiosyncratic 'su' implementations and system utilities customary on
909Android.
910
911+++
906*** New connection methods "dockercp" and "podmancp". 912*** New connection methods "dockercp" and "podmancp".
907These are the external methods counterparts of "docker" and "podman". 913These are the external methods counterparts of "docker" and "podman".
908 914
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 96625fc5680..4f04912c032 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -263,9 +263,10 @@ arguments to pass to the OPERATION."
263 (tramp-convert-file-attributes v localname id-format 263 (tramp-convert-file-attributes v localname id-format
264 (and 264 (and
265 (tramp-adb-send-command-and-check 265 (tramp-adb-send-command-and-check
266 v (format "%s -d -l %s | cat" 266 v (format "(%s -d -l %s; echo tramp_exit_status $?) | cat"
267 (tramp-adb-get-ls-command v) 267 (tramp-adb-get-ls-command v)
268 (tramp-shell-quote-argument localname))) 268 (tramp-shell-quote-argument localname))
269 nil t)
269 (with-current-buffer (tramp-get-buffer v) 270 (with-current-buffer (tramp-get-buffer v)
270 (tramp-adb-sh-fix-ls-output) 271 (tramp-adb-sh-fix-ls-output)
271 (cdar (tramp-do-parse-file-attributes-with-ls v))))))) 272 (cdar (tramp-do-parse-file-attributes-with-ls v)))))))
@@ -316,9 +317,10 @@ arguments to pass to the OPERATION."
316 directory full match nosort id-format count 317 directory full match nosort id-format count
317 (with-current-buffer (tramp-get-buffer v) 318 (with-current-buffer (tramp-get-buffer v)
318 (when (tramp-adb-send-command-and-check 319 (when (tramp-adb-send-command-and-check
319 v (format "%s -a -l %s | cat" 320 v (format "(%s -a -l %s; echo tramp_exit_status $?) | cat"
320 (tramp-adb-get-ls-command v) 321 (tramp-adb-get-ls-command v)
321 (tramp-shell-quote-argument localname))) 322 (tramp-shell-quote-argument localname))
323 nil t)
322 ;; We insert also filename/. and filename/.., because "ls" 324 ;; We insert also filename/. and filename/.., because "ls"
323 ;; doesn't on some file systems, like "sdcard". 325 ;; doesn't on some file systems, like "sdcard".
324 (unless (search-backward-regexp (rx "." eol) nil t) 326 (unless (search-backward-regexp (rx "." eol) nil t)
@@ -440,10 +442,12 @@ Emacs dired can't find files."
440 filename 442 filename
441 (with-parsed-tramp-file-name (expand-file-name directory) nil 443 (with-parsed-tramp-file-name (expand-file-name directory) nil
442 (with-tramp-file-property v localname "file-name-all-completions" 444 (with-tramp-file-property v localname "file-name-all-completions"
443 (tramp-adb-send-command 445 (unless (tramp-adb-send-command-and-check
444 v (format "%s -a %s | cat" 446 v (format "(%s -a %s; echo tramp_exit_status $?) | cat"
445 (tramp-adb-get-ls-command v) 447 (tramp-adb-get-ls-command v)
446 (tramp-shell-quote-argument localname))) 448 (tramp-shell-quote-argument localname))
449 nil t)
450 (erase-buffer))
447 (mapcar 451 (mapcar
448 (lambda (f) 452 (lambda (f)
449 (if (file-directory-p (expand-file-name f directory)) 453 (if (file-directory-p (expand-file-name f directory))
@@ -637,10 +641,23 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
637 ;; because `file-attributes' reads the values from 641 ;; because `file-attributes' reads the values from
638 ;; there. 642 ;; there.
639 (tramp-flush-file-properties v localname) 643 (tramp-flush-file-properties v localname)
640 (unless (tramp-adb-execute-adb-command 644 (unless (if (tramp-adb-file-name-p v)
641 v "push" 645 (tramp-adb-execute-adb-command
642 (file-name-unquote filename) 646 v "push"
643 (file-name-unquote localname)) 647 (file-name-unquote filename)
648 (file-name-unquote localname))
649 ;; Otherwise, this operation was initiated
650 ;; by the androidsu backend, so both files
651 ;; must be present on the local machine and
652 ;; transferable with a simple local copy.
653 (tramp-adb-send-command-and-check
654 v
655 (format
656 "cp -f %s %s"
657 (tramp-shell-quote-argument
658 (file-name-unquote filename))
659 (tramp-shell-quote-argument
660 (file-name-unquote localname)))))
644 (tramp-error 661 (tramp-error
645 v 'file-error 662 v 'file-error
646 "Cannot copy `%s' `%s'" filename newname))))))))) 663 "Cannot copy `%s' `%s'" filename newname)))))))))
@@ -1110,7 +1127,9 @@ error and non-nil on success."
1110 1127
1111(defun tramp-adb-send-command (vec command &optional neveropen nooutput) 1128(defun tramp-adb-send-command (vec command &optional neveropen nooutput)
1112 "Send the COMMAND to connection VEC." 1129 "Send the COMMAND to connection VEC."
1113 (if (string-match-p (rx multibyte) command) 1130 (if (and (equal (tramp-file-name-method vec)
1131 tramp-androidsu-method)
1132 (string-match-p (rx multibyte) command))
1114 ;; Multibyte codepoints with four bytes are not supported at 1133 ;; Multibyte codepoints with four bytes are not supported at
1115 ;; least by toybox. 1134 ;; least by toybox.
1116 1135
@@ -1142,17 +1161,22 @@ error and non-nil on success."
1142 (while (search-forward-regexp (rx (+ "\r") eol) nil t) 1161 (while (search-forward-regexp (rx (+ "\r") eol) nil t)
1143 (replace-match "" nil nil))))))) 1162 (replace-match "" nil nil)))))))
1144 1163
1145(defun tramp-adb-send-command-and-check (vec command &optional exit-status) 1164(defun tramp-adb-send-command-and-check (vec command &optional exit-status
1165 command-augmented-p)
1146 "Run COMMAND and check its exit status. 1166 "Run COMMAND and check its exit status.
1147Sends `echo $?' along with the COMMAND for checking the exit 1167Sends `echo $?' along with the COMMAND for checking the exit
1148status. If COMMAND is nil, just sends `echo $?'. Returns nil if 1168status. If COMMAND is nil, just sends `echo $?'. Returns nil if
1149the exit status is not equal 0, and t otherwise. 1169the exit status is not equal 0, and t otherwise.
1150 1170
1171If COMMAND-AUGMENTED-P, COMMAND is already configured to print exit
1172status upon completion and need not be modified.
1173
1151Optional argument EXIT-STATUS, if non-nil, triggers the return of 1174Optional argument EXIT-STATUS, if non-nil, triggers the return of
1152the exit status." 1175the exit status."
1153 (tramp-adb-send-command 1176 (tramp-adb-send-command
1154 vec (if command 1177 vec (if command
1155 (format "%s; echo tramp_exit_status $?" command) 1178 (if command-augmented-p command
1179 (format "%s; echo tramp_exit_status $?" command))
1156 "echo tramp_exit_status $?")) 1180 "echo tramp_exit_status $?"))
1157 (with-current-buffer (tramp-get-connection-buffer vec) 1181 (with-current-buffer (tramp-get-connection-buffer vec)
1158 (unless (tramp-search-regexp (rx "tramp_exit_status " (+ digit))) 1182 (unless (tramp-search-regexp (rx "tramp_exit_status " (+ digit)))
diff --git a/lisp/net/tramp-androidsu.el b/lisp/net/tramp-androidsu.el
new file mode 100644
index 00000000000..417ef25ed8a
--- /dev/null
+++ b/lisp/net/tramp-androidsu.el
@@ -0,0 +1,537 @@
1;;; tramp-androidsu.el --- TRAMP method for Android superuser shells -*- lexical-binding:t -*-
2
3;; Copyright (C) 2024 Free Software Foundation, Inc.
4
5;; Keywords: comm, processes
6;; Package: tramp
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;; The `su' method struggles (as do other shell-based methods) with the
26;; crippled versions of many Unix utilities installed on Android,
27;; workarounds for which are implemented in the `adb' method. This
28;; method defines a shell-based method that is identical in function to
29;; `su', but reuses such code from the `adb' method where applicable and
30;; also provides for certain mannerisms of popular Android `su'
31;; implementations.
32
33;;; Code:
34
35(require 'tramp)
36(require 'tramp-adb)
37(require 'tramp-sh)
38
39;;;###tramp-autoload
40(defconst tramp-androidsu-method "androidsu"
41 "When this method name is used, forward all calls to su.")
42
43;;;###tramp-autoload
44(tramp--with-startup
45 (add-to-list 'tramp-methods
46 `(,tramp-androidsu-method
47 (tramp-login-program "su")
48 (tramp-login-args (("-") ("%u")))
49 (tramp-remote-shell "/system/bin/sh")
50 (tramp-remote-shell-login ("-l"))
51 (tramp-remote-shell-args ("-c"))
52 (tramp-tmpdir "/data/local/tmp")
53 (tramp-connection-timeout 10)))
54
55 (add-to-list 'tramp-default-host-alist
56 `(,tramp-androidsu-method nil "localhost")))
57
58(defun tramp-androidsu-maybe-open-connection (vec)
59 "Open a connection VEC if not already open.
60Mostly identical to `tramp-adb-maybe-open-connection', but also disables
61multibyte mode and waits for the shell prompt to appear."
62 ;; During completion, don't reopen a new connection.
63 (unless (tramp-connectable-p vec)
64 (throw 'non-essential 'non-essential))
65
66 (with-tramp-debug-message vec "Opening connection"
67 (let ((p (tramp-get-connection-process vec))
68 (process-name (tramp-get-connection-property vec "process-name"))
69 (process-environment (copy-sequence process-environment)))
70 ;; Open a new connection.
71 (condition-case err
72 (unless (process-live-p p)
73 (with-tramp-progress-reporter
74 vec 3
75 (if (tramp-string-empty-or-nil-p (tramp-file-name-user vec))
76 (format "Opening connection %s for %s using %s"
77 process-name
78 (tramp-file-name-host vec)
79 (tramp-file-name-method vec))
80 (format "Opening connection %s for %s@%s using %s"
81 process-name
82 (tramp-file-name-user vec)
83 (tramp-file-name-host vec)
84 (tramp-file-name-method vec)))
85 (let* ((coding-system-for-read 'utf-8-unix)
86 (process-connection-type tramp-process-connection-type)
87 (p (apply
88 #'start-process
89 (tramp-get-connection-name vec)
90 (tramp-get-connection-buffer vec)
91 (append
92 `(,tramp-encoding-shell)
93 (and tramp-encoding-command-interactive
94 `(,tramp-encoding-command-interactive)))))
95 (user (tramp-file-name-user vec))
96 command)
97 ;; Set sentinel. Initialize variables.
98 (set-process-sentinel p #'tramp-process-sentinel)
99 (tramp-post-process-creation p vec)
100
101 ;; Replace `login-args' place holders.
102 (setq command (format "exec su - %s || exit"
103 (or user "root")))
104 ;; Send the command.
105 (tramp-message vec 3 "Sending command `%s'" command)
106 (tramp-adb-send-command vec command t t)
107
108 ;; Android su binaries contact a background service to
109 ;; obtain authentication; during this process, input
110 ;; received is discarded, so input cannot be
111 ;; guaranteed to reach the root shell until its prompt
112 ;; is displayed.
113 (with-current-buffer (process-buffer p)
114 (tramp-wait-for-regexp p tramp-connection-timeout
115 "#[[:space:]]*$"))
116
117 ;; Set connection-local variables.
118 (tramp-set-connection-local-variables vec)
119
120 ;; Change prompt.
121 (tramp-adb-send-command
122 vec (format "PS1=%s"
123 (tramp-shell-quote-argument tramp-end-of-output)))
124
125 ;; Disable line editing.
126 (tramp-adb-send-command
127 vec "set +o vi +o vi-esccomplete +o vi-tabcomplete +o emacs")
128
129 ;; Dump option settings in the traces.
130 (when (>= tramp-verbose 9)
131 (tramp-adb-send-command vec "set -o"))
132
133 ;; Disable Unicode.
134 (tramp-adb-send-command vec "set +U")
135
136 ;; Disable echo expansion.
137 (tramp-adb-send-command
138 vec "stty -inlcr -onlcr -echo kill '^U' erase '^H'" t)
139
140 ;; Check whether the echo has really been disabled.
141 ;; Some implementations, like busybox, don't support
142 ;; disabling.
143 (tramp-adb-send-command vec "echo foo" t)
144 (with-current-buffer (process-buffer p)
145 (goto-char (point-min))
146 (when (looking-at-p "echo foo")
147 (tramp-set-connection-property p "remote-echo" t)
148 (tramp-message vec 5 "Remote echo still on. Ok.")
149 ;; Make sure backspaces and their echo are enabled
150 ;; and no line width magic interferes with them.
151 (tramp-adb-send-command vec
152 "stty icanon erase ^H cols 32767"
153 t)))
154
155 ;; Set the remote PATH to a suitable value.
156 (tramp-set-connection-property vec "remote-path"
157 "/system/bin:/system/xbin")
158
159 ;; Mark it as connected.
160 (tramp-set-connection-property p "connected" t))))
161
162 ;; Cleanup, and propagate the signal.
163 ((error quit)
164 (tramp-cleanup-connection vec t)
165 (signal (car err) (cdr err)))))))
166
167(defun tramp-androidsu-generate-wrapper (function)
168 "Return connection wrapper function for FUNCTION.
169Return a function which temporarily substitutes local replacements for
170the `adb' method's connection management functions around a call to
171FUNCTION."
172 (lambda (&rest args)
173 (let ((tramp-adb-wait-for-output
174 (symbol-function #'tramp-adb-wait-for-output))
175 (tramp-adb-maybe-open-connection
176 (symbol-function #'tramp-adb-maybe-open-connection)))
177 (unwind-protect
178 (progn
179 ;; tramp-adb-wait-for-output addresses problems introduced
180 ;; by the adb utility itself, not Android utilities, so
181 ;; replace it with the regular TRAMP function.
182 (fset 'tramp-adb-wait-for-output #'tramp-wait-for-output)
183 ;; Likewise, except some special treatment is necessary on
184 ;; account of flaws in Android's su implementation.
185 (fset 'tramp-adb-maybe-open-connection
186 #'tramp-androidsu-maybe-open-connection)
187 (apply function args))
188 ;; Restore the original definitions of the functions overridden
189 ;; above.
190 (fset 'tramp-adb-wait-for-output tramp-adb-wait-for-output)
191 (fset 'tramp-adb-maybe-open-connection tramp-adb-maybe-open-connection)))))
192
193(defalias 'tramp-androidsu-handle-access-file
194 (tramp-androidsu-generate-wrapper #'tramp-handle-access-file))
195
196(defalias 'tramp-androidsu-handle-add-name-to-file
197 (tramp-androidsu-generate-wrapper #'tramp-handle-add-name-to-file))
198
199(defalias 'tramp-androidsu-handle-copy-directory
200 (tramp-androidsu-generate-wrapper #'tramp-handle-copy-directory))
201
202(defalias 'tramp-androidsu-adb-handle-copy-file
203 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-copy-file))
204
205(defalias 'tramp-androidsu-adb-handle-delete-directory
206 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-delete-directory))
207
208(defalias 'tramp-androidsu-adb-handle-delete-file
209 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-delete-file))
210
211(defalias 'tramp-androidsu-handle-directory-file-name
212 (tramp-androidsu-generate-wrapper #'tramp-handle-directory-file-name))
213
214(defalias 'tramp-androidsu-handle-directory-files
215 (tramp-androidsu-generate-wrapper #'tramp-handle-directory-files))
216
217(defalias 'tramp-androidsu-adb-handle-directory-files-and-attributes
218 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-directory-files-and-attributes))
219
220(defalias 'tramp-androidsu-handle-dired-uncache
221 (tramp-androidsu-generate-wrapper #'tramp-handle-dired-uncache))
222
223(defalias 'tramp-androidsu-adb-handle-exec-path
224 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-exec-path))
225
226(defalias 'tramp-androidsu-handle-expand-file-name
227 (tramp-androidsu-generate-wrapper #'tramp-handle-expand-file-name))
228
229(defalias 'tramp-androidsu-handle-file-accessible-directory-p
230 (tramp-androidsu-generate-wrapper #'tramp-handle-file-accessible-directory-p))
231
232(defalias 'tramp-androidsu-adb-handle-file-attributes
233 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-attributes))
234
235(defalias 'tramp-androidsu-handle-file-directory-p
236 (tramp-androidsu-generate-wrapper #'tramp-handle-file-directory-p))
237
238(defalias 'tramp-androidsu-handle-file-equal-p
239 (tramp-androidsu-generate-wrapper #'tramp-handle-file-equal-p))
240
241(defalias 'tramp-androidsu-adb-handle-file-executable-p
242 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-executable-p))
243
244(defalias 'tramp-androidsu-adb-handle-file-exists-p
245 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-exists-p))
246
247(defalias 'tramp-androidsu-handle-file-group-gid
248 (tramp-androidsu-generate-wrapper #'tramp-handle-file-group-gid))
249
250(defalias 'tramp-androidsu-handle-file-in-directory-p
251 (tramp-androidsu-generate-wrapper #'tramp-handle-file-in-directory-p))
252
253(defalias 'tramp-androidsu-sh-handle-file-local-copy
254 (tramp-androidsu-generate-wrapper #'tramp-sh-handle-file-local-copy))
255
256(defalias 'tramp-androidsu-handle-file-locked-p
257 (tramp-androidsu-generate-wrapper #'tramp-handle-file-locked-p))
258
259(defalias 'tramp-androidsu-handle-file-modes
260 (tramp-androidsu-generate-wrapper #'tramp-handle-file-modes))
261
262(defalias 'tramp-androidsu-adb-handle-file-name-all-completions
263 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-name-all-completions))
264
265(defalias 'tramp-androidsu-handle-file-name-as-directory
266 (tramp-androidsu-generate-wrapper #'tramp-handle-file-name-as-directory))
267
268(defalias 'tramp-androidsu-handle-file-name-case-insensitive-p
269 (tramp-androidsu-generate-wrapper #'tramp-handle-file-name-case-insensitive-p))
270
271(defalias 'tramp-androidsu-handle-file-name-completion
272 (tramp-androidsu-generate-wrapper #'tramp-handle-file-name-completion))
273
274(defalias 'tramp-androidsu-handle-file-name-directory
275 (tramp-androidsu-generate-wrapper #'tramp-handle-file-name-directory))
276
277(defalias 'tramp-androidsu-handle-file-name-nondirectory
278 (tramp-androidsu-generate-wrapper #'tramp-handle-file-name-nondirectory))
279
280(defalias 'tramp-androidsu-handle-file-newer-than-file-p
281 (tramp-androidsu-generate-wrapper #'tramp-handle-file-newer-than-file-p))
282
283(defalias 'tramp-androidsu-handle-file-notify-add-watch
284 (tramp-androidsu-generate-wrapper #'tramp-handle-file-notify-add-watch))
285
286(defalias 'tramp-androidsu-handle-file-notify-rm-watch
287 (tramp-androidsu-generate-wrapper #'tramp-handle-file-notify-rm-watch))
288
289(defalias 'tramp-androidsu-handle-file-notify-valid-p
290 (tramp-androidsu-generate-wrapper #'tramp-handle-file-notify-valid-p))
291
292(defalias 'tramp-androidsu-adb-handle-file-readable-p
293 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-readable-p))
294
295(defalias 'tramp-androidsu-handle-file-regular-p
296 (tramp-androidsu-generate-wrapper #'tramp-handle-file-regular-p))
297
298(defalias 'tramp-androidsu-handle-file-remote-p
299 (tramp-androidsu-generate-wrapper #'tramp-handle-file-remote-p))
300
301(defalias 'tramp-androidsu-handle-file-selinux-context
302 (tramp-androidsu-generate-wrapper #'tramp-handle-file-selinux-context))
303
304(defalias 'tramp-androidsu-handle-file-symlink-p
305 (tramp-androidsu-generate-wrapper #'tramp-handle-file-symlink-p))
306
307(defalias 'tramp-androidsu-adb-handle-file-system-info
308 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-system-info))
309
310(defalias 'tramp-androidsu-handle-file-truename
311 (tramp-androidsu-generate-wrapper #'tramp-handle-file-truename))
312
313(defalias 'tramp-androidsu-handle-file-user-uid
314 (tramp-androidsu-generate-wrapper #'tramp-handle-file-user-uid))
315
316(defalias 'tramp-androidsu-adb-handle-file-writable-p
317 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-file-writable-p))
318
319(defalias 'tramp-androidsu-handle-find-backup-file-name
320 (tramp-androidsu-generate-wrapper #'tramp-handle-find-backup-file-name))
321
322(defalias 'tramp-androidsu-handle-insert-directory
323 (tramp-androidsu-generate-wrapper #'tramp-handle-insert-directory))
324
325(defalias 'tramp-androidsu-handle-insert-file-contents
326 (tramp-androidsu-generate-wrapper #'tramp-handle-insert-file-contents))
327
328(defalias 'tramp-androidsu-handle-list-system-processes
329 (tramp-androidsu-generate-wrapper #'tramp-handle-list-system-processes))
330
331(defalias 'tramp-androidsu-handle-load
332 (tramp-androidsu-generate-wrapper #'tramp-handle-load))
333
334(defalias 'tramp-androidsu-handle-lock-file
335 (tramp-androidsu-generate-wrapper #'tramp-handle-lock-file))
336
337(defalias 'tramp-androidsu-handle-make-auto-save-file-name
338 (tramp-androidsu-generate-wrapper #'tramp-handle-make-auto-save-file-name))
339
340(defalias 'tramp-androidsu-adb-handle-make-directory
341 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-make-directory))
342
343(defalias 'tramp-androidsu-handle-make-lock-file-name
344 (tramp-androidsu-generate-wrapper #'tramp-handle-make-lock-file-name))
345
346(defalias 'tramp-androidsu-handle-make-nearby-temp-file
347 (tramp-androidsu-generate-wrapper #'tramp-handle-make-nearby-temp-file))
348
349(defalias 'tramp-androidsu-adb-handle-make-process
350 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-make-process))
351
352(defalias 'tramp-androidsu-sh-handle-make-symbolic-link
353 (tramp-androidsu-generate-wrapper
354 #'tramp-sh-handle-make-symbolic-link))
355
356(defalias 'tramp-androidsu-handle-memory-info
357 (tramp-androidsu-generate-wrapper #'tramp-handle-memory-info))
358
359(defalias 'tramp-androidsu-handle-process-attributes
360 (tramp-androidsu-generate-wrapper #'tramp-handle-process-attributes))
361
362(defalias 'tramp-androidsu-adb-handle-process-file
363 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-process-file))
364
365(defalias 'tramp-androidsu-adb-handle-rename-file
366 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-rename-file))
367
368(defalias 'tramp-androidsu-adb-handle-set-file-modes
369 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-set-file-modes))
370
371(defalias 'tramp-androidsu-adb-handle-set-file-times
372 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-set-file-times))
373
374(defalias 'tramp-androidsu-handle-set-visited-file-modtime
375 (tramp-androidsu-generate-wrapper #'tramp-handle-set-visited-file-modtime))
376
377(defalias 'tramp-androidsu-handle-shell-command
378 (tramp-androidsu-generate-wrapper #'tramp-handle-shell-command))
379
380(defalias 'tramp-androidsu-handle-start-file-process
381 (tramp-androidsu-generate-wrapper #'tramp-handle-start-file-process))
382
383(defalias 'tramp-androidsu-handle-substitute-in-file-name
384 (tramp-androidsu-generate-wrapper #'tramp-handle-substitute-in-file-name))
385
386(defalias 'tramp-androidsu-handle-temporary-file-directory
387 (tramp-androidsu-generate-wrapper #'tramp-handle-temporary-file-directory))
388
389(defalias 'tramp-androidsu-adb-handle-get-remote-gid
390 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-get-remote-gid))
391
392(defalias 'tramp-androidsu-adb-handle-get-remote-groups
393 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-get-remote-groups))
394
395(defalias 'tramp-androidsu-adb-handle-get-remote-uid
396 (tramp-androidsu-generate-wrapper #'tramp-adb-handle-get-remote-uid))
397
398(defalias 'tramp-androidsu-handle-unlock-file
399 (tramp-androidsu-generate-wrapper #'tramp-handle-unlock-file))
400
401(defalias 'tramp-androidsu-handle-verify-visited-file-modtime
402 (tramp-androidsu-generate-wrapper #'tramp-handle-verify-visited-file-modtime))
403
404(defalias 'tramp-androidsu-handle-write-region
405 (tramp-androidsu-generate-wrapper #'tramp-handle-write-region))
406
407;;;###tramp-autoload
408(defconst tramp-androidsu-file-name-handler-alist
409 '(;; `abbreviate-file-name' performed by default handler.
410 (access-file . tramp-androidsu-handle-access-file)
411 (add-name-to-file . tramp-androidsu-handle-add-name-to-file)
412 ;; `byte-compiler-base-file-name' performed by default handler.
413 (copy-directory . tramp-androidsu-handle-copy-directory)
414 (copy-file . tramp-androidsu-adb-handle-copy-file)
415 (delete-directory . tramp-androidsu-adb-handle-delete-directory)
416 (delete-file . tramp-androidsu-adb-handle-delete-file)
417 ;; `diff-latest-backup-file' performed by default handler.
418 (directory-file-name . tramp-androidsu-handle-directory-file-name)
419 (directory-files . tramp-androidsu-handle-directory-files)
420 (directory-files-and-attributes
421 . tramp-androidsu-adb-handle-directory-files-and-attributes)
422 (dired-compress-file . ignore)
423 (dired-uncache . tramp-androidsu-handle-dired-uncache)
424 (exec-path . tramp-androidsu-adb-handle-exec-path)
425 (expand-file-name . tramp-androidsu-handle-expand-file-name)
426 (file-accessible-directory-p . tramp-androidsu-handle-file-accessible-directory-p)
427 (file-acl . ignore)
428 (file-attributes . tramp-androidsu-adb-handle-file-attributes)
429 (file-directory-p . tramp-androidsu-handle-file-directory-p)
430 (file-equal-p . tramp-androidsu-handle-file-equal-p)
431 (file-executable-p . tramp-androidsu-adb-handle-file-executable-p)
432 (file-exists-p . tramp-androidsu-adb-handle-file-exists-p)
433 (file-group-gid . tramp-androidsu-handle-file-group-gid)
434 (file-in-directory-p . tramp-androidsu-handle-file-in-directory-p)
435 (file-local-copy . tramp-androidsu-sh-handle-file-local-copy)
436 (file-locked-p . tramp-androidsu-handle-file-locked-p)
437 (file-modes . tramp-androidsu-handle-file-modes)
438 (file-name-all-completions . tramp-androidsu-adb-handle-file-name-all-completions)
439 (file-name-as-directory . tramp-androidsu-handle-file-name-as-directory)
440 (file-name-case-insensitive-p . tramp-androidsu-handle-file-name-case-insensitive-p)
441 (file-name-completion . tramp-androidsu-handle-file-name-completion)
442 (file-name-directory . tramp-androidsu-handle-file-name-directory)
443 (file-name-nondirectory . tramp-androidsu-handle-file-name-nondirectory)
444 ;; `file-name-sans-versions' performed by default handler.
445 (file-newer-than-file-p . tramp-androidsu-handle-file-newer-than-file-p)
446 (file-notify-add-watch . tramp-androidsu-handle-file-notify-add-watch)
447 (file-notify-rm-watch . tramp-androidsu-handle-file-notify-rm-watch)
448 (file-notify-valid-p . tramp-androidsu-handle-file-notify-valid-p)
449 (file-ownership-preserved-p . ignore)
450 (file-readable-p . tramp-androidsu-adb-handle-file-readable-p)
451 (file-regular-p . tramp-androidsu-handle-file-regular-p)
452 (file-remote-p . tramp-androidsu-handle-file-remote-p)
453 (file-selinux-context . tramp-androidsu-handle-file-selinux-context)
454 (file-symlink-p . tramp-androidsu-handle-file-symlink-p)
455 (file-system-info . tramp-androidsu-adb-handle-file-system-info)
456 (file-truename . tramp-androidsu-handle-file-truename)
457 (file-user-uid . tramp-androidsu-handle-file-user-uid)
458 (file-writable-p . tramp-androidsu-adb-handle-file-writable-p)
459 (find-backup-file-name . tramp-androidsu-handle-find-backup-file-name)
460 ;; `get-file-buffer' performed by default handler.
461 (insert-directory . tramp-androidsu-handle-insert-directory)
462 (insert-file-contents . tramp-androidsu-handle-insert-file-contents)
463 (list-system-processes . tramp-androidsu-handle-list-system-processes)
464 (load . tramp-androidsu-handle-load)
465 (lock-file . tramp-androidsu-handle-lock-file)
466 (make-auto-save-file-name . tramp-androidsu-handle-make-auto-save-file-name)
467 (make-directory . tramp-androidsu-adb-handle-make-directory)
468 (make-directory-internal . ignore)
469 (make-lock-file-name . tramp-androidsu-handle-make-lock-file-name)
470 (make-nearby-temp-file . tramp-androidsu-handle-make-nearby-temp-file)
471 (make-process . tramp-androidsu-adb-handle-make-process)
472 (make-symbolic-link . tramp-androidsu-sh-handle-make-symbolic-link)
473 (memory-info . tramp-androidsu-handle-memory-info)
474 (process-attributes . tramp-androidsu-handle-process-attributes)
475 (process-file . tramp-androidsu-adb-handle-process-file)
476 (rename-file . tramp-androidsu-adb-handle-rename-file)
477 (set-file-acl . ignore)
478 (set-file-modes . tramp-androidsu-adb-handle-set-file-modes)
479 (set-file-selinux-context . ignore)
480 (set-file-times . tramp-androidsu-adb-handle-set-file-times)
481 (set-visited-file-modtime . tramp-androidsu-handle-set-visited-file-modtime)
482 (shell-command . tramp-androidsu-handle-shell-command)
483 (start-file-process . tramp-androidsu-handle-start-file-process)
484 (substitute-in-file-name . tramp-androidsu-handle-substitute-in-file-name)
485 (temporary-file-directory . tramp-androidsu-handle-temporary-file-directory)
486 (tramp-get-home-directory . ignore)
487 (tramp-get-remote-gid . tramp-androidsu-adb-handle-get-remote-gid)
488 (tramp-get-remote-groups . tramp-androidsu-adb-handle-get-remote-groups)
489 (tramp-get-remote-uid . tramp-androidsu-adb-handle-get-remote-uid)
490 (tramp-set-file-uid-gid . ignore)
491 (unhandled-file-name-directory . ignore)
492 (unlock-file . tramp-androidsu-handle-unlock-file)
493 (vc-registered . ignore)
494 (verify-visited-file-modtime . tramp-androidsu-handle-verify-visited-file-modtime)
495 (write-region . tramp-androidsu-handle-write-region))
496 "Alist of TRAMP handler functions for superuser sessions on Android.")
497
498;; It must be a `defsubst' in order to push the whole code into
499;; tramp-loaddefs.el. Otherwise, there would be recursive autoloading.
500;;;###tramp-autoload
501(defsubst tramp-androidsu-file-name-p (vec-or-filename)
502 "Check whether VEC-OR-FILENAME is for the `androidsu' method."
503 (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
504 (equal (tramp-file-name-method vec) tramp-androidsu-method)))
505
506;;;###tramp-autoload
507(defun tramp-androidsu-file-name-handler (operation &rest args)
508 "Invoke the `androidsu' handler for OPERATION.
509First arg specifies the OPERATION, second arg is a list of
510arguments to pass to the OPERATION."
511 (if-let ((fn (assoc operation tramp-androidsu-file-name-handler-alist)))
512 (prog1 (save-match-data (apply (cdr fn) args))
513 (setq tramp-debug-message-fnh-function (cdr fn)))
514 (prog1 (tramp-run-real-handler operation args)
515 (setq tramp-debug-message-fnh-function operation))))
516
517;;;###tramp-autoload
518(tramp--with-startup
519 (tramp-register-foreign-file-name-handler
520 #'tramp-androidsu-file-name-p #'tramp-androidsu-file-name-handler))
521
522(connection-local-set-profile-variables
523 'tramp-adb-connection-local-default-ps-profile
524 tramp-adb-connection-local-default-ps-variables)
525
526(with-eval-after-load 'shell
527 (connection-local-set-profiles
528 `(:application tramp :protocol ,tramp-adb-method)
529 'tramp-adb-connection-local-default-shell-profile
530 'tramp-adb-connection-local-default-ps-profile))
531
532(add-hook 'tramp-unload-hook
533 (lambda ()
534 (unload-feature 'tramp-androidsu 'force)))
535
536(provide 'tramp-androidsu)
537;;; tramp-androidsu.el ends here