(defconst tramp-adb-method "adb"
"When this method name is used, forward all calls to Android Debug Bridge.")
-(defcustom tramp-adb-prompt (rx bol (* (not (any "#$\n\r"))) (any "#$") space)
+(defcustom tramp-adb-prompt (rx bol (* (not (any "#$\n\r"))) (any "#$") blank)
"Regexp used as prompt in almquist shell."
:type 'regexp
:version "28.1"
"Regexp for date time format in ls output."))
(defconst tramp-adb-ls-date-regexp
- (rx space (regexp tramp-adb-ls-date-year-regexp)
- space (regexp tramp-adb-ls-date-time-regexp)
- space)
+ (rx blank (regexp tramp-adb-ls-date-year-regexp)
+ blank (regexp tramp-adb-ls-date-time-regexp)
+ blank)
"Regexp for date format in ls output.")
(defconst tramp-adb-ls-toolbox-regexp
- (rx bol (* space) (group (+ (any ".-" alpha))) ; \1 permissions
- (? (+ space) (+ digit)) ; links (Android 7/toybox)
- (* space) (group (+ (not space))) ; \2 username
- (+ space) (group (+ (not space))) ; \3 group
- (+ space) (group (+ digit)) ; \4 size
- (+ space) (group (regexp tramp-adb-ls-date-year-regexp)
- space (regexp tramp-adb-ls-date-time-regexp)) ; \5 date
- space (group (* nonl)) eol) ; \6 filename
+ (rx bol (* blank) (group (+ (any ".-" alpha))) ; \1 permissions
+ (? (+ blank) (+ digit)) ; links (Android 7/toybox)
+ (* blank) (group (+ (not blank))) ; \2 username
+ (+ blank) (group (+ (not blank))) ; \3 group
+ (+ blank) (group (+ digit)) ; \4 size
+ (+ blank) (group (regexp tramp-adb-ls-date-year-regexp)
+ blank (regexp tramp-adb-ls-date-time-regexp)) ; \5 date
+ blank (group (* nonl)) eol) ; \6 filename
"Regexp for ls output.")
;;;###tramp-autoload
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . ignore)
(tramp-get-remote-gid . tramp-adb-handle-get-remote-gid)
+ (tramp-get-remote-groups . tramp-adb-handle-get-remote-groups)
(tramp-get-remote-uid . tramp-adb-handle-get-remote-uid)
(tramp-set-file-uid-gid . ignore)
(unhandled-file-name-directory . ignore)
(mapcar
(lambda (line)
(when (string-match
- (rx bol (group (+ (not space))) (+ space) "device" eol) line)
+ (rx bol (group (+ (not blank))) (+ blank) "device" eol) line)
;; Replace ":" by "#".
`(nil ,(tramp-compat-string-replace
":" tramp-prefix-port-format (match-string 1 line)))))
(goto-char (point-min))
(forward-line)
(when (looking-at
- (rx (* space) (+ (not space))
- (+ space) (group (+ digit))
- (+ space) (group (+ digit))
- (+ space) (group (+ digit))))
+ (rx (* blank) (+ (not blank))
+ (+ blank) (group (+ digit))
+ (+ blank) (group (+ digit))
+ (+ blank) (group (+ digit))))
;; The values are given as 1k numbers, so we must change
;; them to number of bytes.
(list (* 1024 (string-to-number (match-string 1)))
(goto-char (point-min))
(while
(search-forward-regexp
- (rx space (group space (regexp tramp-adb-ls-date-year-regexp) space))
+ (rx blank (group blank (regexp tramp-adb-ls-date-year-regexp) blank))
nil t)
(replace-match "0\\1" "\\1" nil)
;; Insert missing "/".
(when (looking-at-p
- (rx (regexp tramp-adb-ls-date-time-regexp) (+ space) eol))
+ (rx (regexp tramp-adb-ls-date-time-regexp) (+ blank) eol))
(end-of-line)
(insert "/")))
;; Sort entries.
nil
(mapcar
(lambda (l)
- (and (not (string-match-p (rx bol (* space) eol) l)) l))
+ (and (not (string-match-p (rx bol (* blank) eol) l)) l))
(split-string (buffer-string) "\n")))))))))))
(defun tramp-adb-handle-file-local-copy (filename)
(setcar result 0)
(dolist (line signals)
(when (string-match
- (rx bol (* space) (group (+ digit))
- (+ space) (+ (not space))
- (+ space) (group alpha (* nonl)) eol)
+ (rx bol (* blank) (group (+ digit))
+ (+ blank) (+ (not blank))
+ (+ blank) (group alpha (* nonl)) eol)
line)
(setcar
(nthcdr (string-to-number (match-string 1 line)) result)
(goto-char (point-min))
(read (current-buffer))))
+(defun tramp-adb-handle-get-remote-groups (vec id-format)
+ "Like `tramp-get-remote-groups' for Tramp files.
+ID-FORMAT valid values are `string' and `integer'."
+ ;; The result is cached in `tramp-get-remote-groups'.
+ (tramp-adb-send-command vec "id")
+ (with-current-buffer (tramp-get-connection-buffer vec)
+ (let (groups-integer groups-string)
+ ;; Read the expression.
+ (goto-char (point-min))
+ (when (re-search-forward (rx bol (+ nonl) "groups=") nil 'noerror)
+ (while (looking-at
+ (rx (group (+ digit)) "(" (group (+ (any "_" word))) ")"))
+ (setq groups-integer (cons (string-to-number (match-string 1))
+ groups-integer)
+ groups-string (cons (match-string 2) groups-string))
+ (goto-char (match-end 0))
+ (skip-chars-forward ",")))
+ (tramp-set-connection-property
+ vec "groups-integer"
+ (setq groups-integer (nreverse groups-integer)))
+ (tramp-set-connection-property
+ vec "groups-string"
+ (setq groups-string (nreverse groups-string)))
+ (if (eq id-format 'integer) groups-integer groups-string))))
+
(defun tramp-adb-get-device (vec)
"Return full host name from VEC to be used in shell execution.
E.g. a host name \"192.168.1.1#5555\" returns \"192.168.1.1:5555\"
;; We can't use stty to disable echo of command. stty is said
;; to be added to toybox 0.7.6. busybox shall have it, but this
;; isn't used any longer for Android.
- (delete-matching-lines (rx (literal command)))
+ (delete-matching-lines (rx bol (literal command) eol))
;; When the local machine is W32, there are still trailing ^M.
;; There must be a better solution by setting the correct coding
;; system, but this requires changes in core Tramp.
(temporary-file-directory . tramp-archive-handle-temporary-file-directory)
(tramp-get-home-directory . ignore)
(tramp-get-remote-gid . ignore)
+ (tramp-get-remote-groups . ignore)
(tramp-get-remote-uid . ignore)
(tramp-set-file-uid-gid . ignore)
(unhandled-file-name-directory . ignore)
This is suppressed for temporary buffers."
(save-match-data
(unless (or (null (buffer-name))
- (string-match-p (rx bos (| space "*")) (buffer-name)))
+ (string-match-p (rx bos (| blank "*")) (buffer-name)))
(let ((bfn (if (stringp (buffer-file-name))
(buffer-file-name)
default-directory))
(temporary-file-directory . tramp-handle-temporary-file-directory)
;; `tramp-get-home-directory' performed by default-handler.
;; `tramp-get-remote-gid' performed by default handler.
+ ;; `tramp-get-remote-groups' performed by default handler.
;; `tramp-get-remote-uid' performed by default handler.
(tramp-set-file-uid-gid . tramp-crypt-handle-set-file-uid-gid)
(unhandled-file-name-directory . ignore)
(tramp-set-file-property
vec "/" "mounted"
(when (string-match
- (rx bol (group (literal (tramp-fuse-mount-spec vec))) space)
+ (rx bol (group (literal (tramp-fuse-mount-spec vec))) blank)
mount)
(match-string 1 mount)))))))
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . tramp-gvfs-handle-get-home-directory)
(tramp-get-remote-gid . tramp-gvfs-handle-get-remote-gid)
+ (tramp-get-remote-groups . ignore)
(tramp-get-remote-uid . tramp-gvfs-handle-get-remote-uid)
(tramp-set-file-uid-gid . tramp-gvfs-handle-set-file-uid-gid)
(unhandled-file-name-directory . ignore)
(while (string-match
(rx bol (+ nonl) ":"
- space (group (+ nonl)) ":"
- space (group (regexp (regexp-opt tramp-gio-events)))
- (? (group space (group (+ nonl)))) eol)
+ blank (group (+ nonl)) ":"
+ blank (group (regexp (regexp-opt tramp-gio-events)))
+ (? (group blank (group (+ nonl)))) eol)
string)
(let ((file (match-string 1 string))
:mode 'tramp-info-lookup-mode :topic 'symbol
:regexp (rx (+ (not (any "\t\n \"'(),[]`‘’"))))
:doc-spec '(("(tramp)Function Index" nil
- (rx bol space (+ "-") space (* nonl) ": ")
- (rx (| space eol)))
+ (rx bol blank (+ "-") blank (* nonl) ": ")
+ (rx (| blank eol)))
("(tramp)Variable Index" nil
- (rx bol space (+ "-") space (* nonl) ": ")
- (rx (| space eol)))))
+ (rx bol blank (+ "-") blank (* nonl) ": ")
+ (rx (| blank eol)))))
(add-hook
'tramp-integration-unload-hook
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . ignore)
(tramp-get-remote-gid . ignore)
+ (tramp-get-remote-groups . ignore)
(tramp-get-remote-uid . ignore)
(tramp-set-file-uid-gid . ignore)
(unhandled-file-name-directory . ignore)
(delq nil
(mapcar
(lambda (line)
- (when (string-match (rx bol (group (+ (not space))) ":" eol) line)
+ (when (string-match (rx bol (group (+ (not blank))) ":" eol) line)
`(nil ,(match-string 1 line))))
(tramp-process-lines nil tramp-rclone-program "listremotes")))))
(let (total used free)
(goto-char (point-min))
(while (not (eobp))
- (when (looking-at (rx "Total: " (+ space) (group (+ digit))))
+ (when (looking-at (rx "Total: " (+ blank) (group (+ digit))))
(setq total (string-to-number (match-string 1))))
- (when (looking-at (rx "Used: " (+ space) (group (+ digit))))
+ (when (looking-at (rx "Used: " (+ blank) (group (+ digit))))
(setq used (string-to-number (match-string 1))))
- (when (looking-at (rx "Free: " (+ space) (group (+ digit))))
+ (when (looking-at (rx "Free: " (+ blank) (group (+ digit))))
(setq free (string-to-number (match-string 1))))
(forward-line))
(when used
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . tramp-sh-handle-get-home-directory)
(tramp-get-remote-gid . tramp-sh-handle-get-remote-gid)
+ (tramp-get-remote-groups . tramp-sh-handle-get-remote-groups)
(tramp-get-remote-uid . tramp-sh-handle-get-remote-uid)
(tramp-set-file-uid-gid . tramp-sh-handle-set-file-uid-gid)
(unhandled-file-name-directory . ignore)
((tramp-get-remote-python vec)
(tramp-get-remote-gid-with-python vec id-format)))))
+(defun tramp-sh-handle-get-remote-groups (vec id-format)
+ "Like `tramp-get-remote-groups' for Tramp files.
+ID-FORMAT valid values are `string' and `integer'."
+ ;; The result is cached in `tramp-get-remote-groups'.
+ (when (tramp-get-remote-id vec)
+ (tramp-send-command vec (tramp-get-remote-id vec)))
+ (with-current-buffer (tramp-get-connection-buffer vec)
+ (let (groups-integer groups-string)
+ ;; Read the expression.
+ (goto-char (point-min))
+ (when (re-search-forward (rx bol (+ nonl) "groups=") nil 'noerror)
+ (while (looking-at
+ (rx (group (+ digit)) "(" (group (+ (any "_" word))) ")"))
+ (setq groups-integer (cons (string-to-number (match-string 1))
+ groups-integer)
+ groups-string (cons (match-string 2) groups-string))
+ (goto-char (match-end 0))
+ (skip-chars-forward ",")))
+ (tramp-set-connection-property
+ vec "groups-integer"
+ (setq groups-integer (nreverse groups-integer)))
+ (tramp-set-connection-property
+ vec "groups-string"
+ (setq groups-string (nreverse groups-string)))
+ (if (eq id-format 'integer) groups-integer groups-string))))
+
(defun tramp-sh-handle-set-file-uid-gid (filename &optional uid gid)
"Like `tramp-set-file-uid-gid' for Tramp files."
;; Modern Unices allow chown only for root. So we might need
(narrow-to-region beg-marker end-marker)
;; Check for "--dired" output.
(when (re-search-backward
- (rx bol "//DIRED//" (+ space) (group (+ nonl)) eol)
+ (rx bol "//DIRED//" (+ blank) (group (+ nonl)) eol)
nil 'noerror)
(let ((beg (match-beginning 1))
(end (match-end 0)))
;; Try to insert the amount of free space.
(goto-char (point-min))
;; First find the line to put it on.
- (when (and (re-search-forward (rx bol (group (* space) "total")) nil t)
+ (when (and (re-search-forward (rx bol (group (* blank) "total")) nil t)
;; Emacs 29.1 or later.
(not (fboundp 'dired--insert-disk-space)))
(when-let ((available (get-free-disk-space ".")))
((string-match
(rx "Supported arguments for "
"GIO_USE_FILE_MONITOR environment variable:\n"
- (* space) (group (+ alpha)) " - 20")
+ (* blank) (group (+ alpha)) " - 20")
string)
(setq pos (match-end 0))
(intern
(setq string (tramp-compat-string-replace "\n\n" "\n" string))
(while (string-match
- (rx bol (+ (not (any ":"))) ":" space
- (group (+ (not (any ":")))) ":" space
+ (rx bol (+ (not (any ":"))) ":" blank
+ (group (+ (not (any ":")))) ":" blank
(group (regexp (regexp-opt tramp-gio-events)))
- (? space (group (+ (not (any ":"))))) eol)
+ (? blank (group (+ (not (any ":"))))) eol)
string)
(let* ((file (match-string 1 string))
(goto-char (point-min))
(forward-line)
(when (looking-at
- (rx (? bol "/" (* (not space)) space) (* space)
- (group (+ digit)) (+ space)
- (group (+ digit)) (+ space)
+ (rx (? bol "/" (* (not blank)) blank) (* blank)
+ (group (+ digit)) (+ blank)
+ (group (+ digit)) (+ blank)
(group (+ digit))))
(mapcar
(lambda (d)
(unless (or ignore-path (tramp-check-remote-uname vec tramp-sunos-unames))
(tramp-send-command vec (format "which \\%s | wc -w" progname))
(goto-char (point-min))
- (if (looking-at-p (rx bol (* space) "1" eol))
+ (if (looking-at-p (rx bol (* blank) "1" eol))
(setq result (concat "\\" progname))))
(unless result
(when ignore-tilde
string
(and
(string-match
- (rx bol (+ (not (any space "#"))) space
- (+ (not space)) space
- (group (+ (not space))) eol)
+ (rx bol (+ (not (any blank "#"))) blank
+ (+ (not blank)) blank
+ (group (+ (not blank))) eol)
string)
(match-string 1 string))
found
(unless noerror signal-hook-function)))
(read (current-buffer)))
;; Error handling.
- (when (re-search-forward (rx (not space)) (line-end-position) t)
+ (when (re-search-forward (rx (not blank)) (line-end-position) t)
(error nil)))
(error (unless noerror
(tramp-error
"Regexp of SMB server identification.")
(defconst tramp-smb-prompt
- (rx bol (| (: (| "smb:" "PS") space (+ nonl) "> ")
- (: (+ space) "Server"
- (+ space) "Comment" eol)))
+ (rx bol (| (: (| "smb:" "PS") blank (+ nonl) "> ")
+ (: (+ blank) "Server"
+ (+ blank) "Comment" eol)))
"Regexp used as prompt in smbclient or powershell.")
(defconst tramp-smb-wrong-passwd-regexp
(defconst tramp-smb-errors
(rx (| ;; Connection error / timeout / unknown command.
- (: "Connection" (? " to " (+ (not space))) " failed")
+ (: "Connection" (? " to " (+ (not blank))) " failed")
"Read from server failed, maybe it closed the connection"
"Call timed out: server did not respond"
- (: (+ (not space)) ": command not found")
+ (: (+ (not blank)) ": command not found")
"Server doesn't support UNIX CIFS calls"
(| ;; Samba.
"ERRDOS"
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . tramp-smb-handle-get-home-directory)
(tramp-get-remote-gid . ignore)
+ (tramp-get-remote-groups . ignore)
(tramp-get-remote-uid . ignore)
(tramp-set-file-uid-gid . ignore)
(unhandled-file-name-directory . ignore)
(while (not (eobp))
(cond
((looking-at
- (rx "Size:" (+ space) (group (+ digit)) (+ space)
- "Blocks:" (+ space) (+ digit) (+ space) (group (+ wordchar))))
+ (rx "Size:" (+ blank) (group (+ digit)) (+ blank)
+ "Blocks:" (+ blank) (+ digit) (+ blank) (group (+ wordchar))))
(setq size (string-to-number (match-string 1))
id (if (string-equal "directory" (match-string 2)) t
(if (string-equal "symbolic" (match-string 2)) ""))))
((looking-at
- (rx "Inode:" (+ space) (group (+ digit)) (+ space)
- "Links:" (+ space) (group (+ digit))))
+ (rx "Inode:" (+ blank) (group (+ digit)) (+ blank)
+ "Links:" (+ blank) (group (+ digit))))
(setq inode (string-to-number (match-string 1))
link (string-to-number (match-string 2))))
((looking-at
- (rx "Access:" (+ space)
- "(" (+ digit) "/" (group (+ (not space))) ")" (+ space)
- "Uid:" (+ space) (group (+ digit)) (+ whitespace)
- "Gid:" (+ space) (group (+ digit))))
+ (rx "Access:" (+ blank)
+ "(" (+ digit) "/" (group (+ (not blank))) ")" (+ blank)
+ "Uid:" (+ blank) (group (+ digit)) (+ blank)
+ "Gid:" (+ blank) (group (+ digit))))
(setq mode (match-string 1)
uid (match-string 2)
gid (match-string 3)))
((looking-at
- (rx "Access:" (+ space)
+ (rx "Access:" (+ blank)
(group (+ digit)) "-" (group (+ digit)) "-"
- (group (+ digit)) (+ space)
+ (group (+ digit)) (+ blank)
(group (+ digit)) ":" (group (+ digit)) ":"
(group (+ digit))))
(setq atime
(string-to-number (match-string 2)) ;; month
(string-to-number (match-string 1))))) ;; year
((looking-at
- (rx "Modify:" (+ space)
+ (rx "Modify:" (+ blank)
(group (+ digit)) "-" (group (+ digit)) "-"
- (group (+ digit)) (+ space)
+ (group (+ digit)) (+ blank)
(group (+ digit)) ":" (group (+ digit)) ":"
(group (+ digit))))
(setq mtime
(string-to-number (match-string 2)) ;; month
(string-to-number (match-string 1))))) ;; year
((looking-at
- (rx "Change:" (+ space)
+ (rx "Change:" (+ blank)
(group (+ digit)) "-" (group (+ digit)) "-"
- (group (+ digit)) (+ space)
+ (group (+ digit)) (+ blank)
(group (+ digit)) ":" (group (+ digit)) ":"
(group (+ digit))))
(setq ctime
(goto-char (point-min))
(forward-line)
(when (looking-at
- (rx (* space) (group (+ digit))
+ (rx (* blank) (group (+ digit))
" blocks of size " (group (+ digit))
". " (group (+ digit)) " blocks available"))
(setq blocksize (string-to-number (match-string 2))
(setq localname (replace-match "$" nil nil localname 1)))
;; A trailing space is not supported.
- (when (string-match-p (rx space eol) localname)
+ (when (string-match-p (rx blank eol) localname)
(tramp-error
vec 'file-error
"Invalid file name %s" (tramp-make-tramp-file-name vec localname)))
;; localname.
(if (string-match
- (rx bol (+ space)
- (group (not space) (? (* nonl) (not space)))
- (* space) eol)
+ (rx bol (+ blank)
+ (group (not blank) (? (* nonl) (not blank)))
+ (* blank) eol)
line)
(setq localname (match-string 1 line))
(cl-return))))
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . ignore)
(tramp-get-remote-gid . ignore)
+ (tramp-get-remote-groups . ignore)
(tramp-get-remote-uid . ignore)
(tramp-set-file-uid-gid . ignore)
(unhandled-file-name-directory . ignore)
(temporary-file-directory . tramp-handle-temporary-file-directory)
(tramp-get-home-directory . tramp-sudoedit-handle-get-home-directory)
(tramp-get-remote-gid . tramp-sudoedit-handle-get-remote-gid)
+ (tramp-get-remote-groups . tramp-sudoedit-handle-get-remote-groups)
(tramp-get-remote-uid . tramp-sudoedit-handle-get-remote-uid)
(tramp-set-file-uid-gid . tramp-sudoedit-handle-set-file-uid-gid)
(unhandled-file-name-directory . ignore)
(delq
nil
(mapcar
- (lambda (l) (and (not (string-match-p (rx bol (* space) eol) l)) l))
+ (lambda (l) (and (not (string-match-p (rx bol (* blank) eol) l)) l))
(split-string
(tramp-get-buffer-string (tramp-get-connection-buffer v))
"\n" 'omit))))))))
(goto-char (point-min))
(forward-line)
(when (looking-at
- (rx (* space) (group (+ digit))
- (+ space) (group (+ digit))
- (+ space) (group (+ digit))))
+ (rx (* blank) (group (+ digit))
+ (+ blank) (group (+ digit))
+ (+ blank) (group (+ digit))))
(list (string-to-number (match-string 1))
;; The second value is the used size. We need the
;; free size.
(tramp-sudoedit-send-command-and-read vec "id" "-g")
(tramp-sudoedit-send-command-string vec "id" "-gn")))
+(defun tramp-sudoedit-handle-get-remote-groups (vec id-format)
+ "Like `tramp-get-remote-groups' for Tramp files.
+ID-FORMAT valid values are `string' and `integer'."
+ ;; The result is cached in `tramp-get-remote-groups'.
+ (tramp-sudoedit-send-command vec "id")
+ (with-current-buffer (tramp-get-connection-buffer vec)
+ (let (groups-integer groups-string)
+ ;; Read the expression.
+ (goto-char (point-min))
+ (when (re-search-forward (rx bol (+ nonl) "groups=") nil 'noerror)
+ (while (looking-at
+ (rx (group (+ digit)) "(" (group (+ (any "_" word))) ")"))
+ (setq groups-integer (cons (string-to-number (match-string 1))
+ groups-integer)
+ groups-string (cons (match-string 2) groups-string))
+ (goto-char (match-end 0))
+ (skip-chars-forward ",")))
+ (tramp-set-connection-property
+ vec "groups-integer"
+ (setq groups-integer (nreverse groups-integer)))
+ (tramp-set-connection-property
+ vec "groups-string"
+ (setq groups-string (nreverse groups-string)))
+ (if (eq id-format 'integer) groups-integer groups-string))))
+
(defun tramp-sudoedit-handle-set-file-uid-gid (filename &optional uid gid)
"Like `tramp-set-file-uid-gid' for Tramp files."
(tramp-skeleton-set-file-modes-times-uid-gid filename
(condition-case nil
(prog1 (read (current-buffer))
;; Error handling.
- (when (re-search-forward (rx (not space)) (line-end-position) t)
+ (when (re-search-forward (rx (not blank)) (line-end-position) t)
(error nil)))
(error (tramp-error
vec 'file-error
:type 'string)
(defcustom tramp-login-prompt-regexp
- (rx (* nonl) (| "user" "login") (? space (* nonl)) ":" (* space))
+ (rx (* nonl) (| "user" "login") (? blank (* nonl)) ":" (* blank))
"Regexp matching login-like prompts.
The regexp should match at end of buffer.
;; connection initialization; Tramp redefines the prompt afterwards.
(rx (| bol "\r")
(* (not (any "\n#$%>]")))
- (? "#") (any "#$%>]") (* space)
+ (? "#") (any "#$%>]") (* blank)
;; Escape characters.
- (* "\e[" (* (any ";" digit)) alpha (* space)))
+ (* "\e[" (* (any ";" digit)) alpha (* blank)))
"Regexp to match prompts from remote shell.
Normally, Tramp expects you to configure `shell-prompt-pattern'
correctly, but sometimes it happens that you are connecting to a
(defcustom tramp-password-prompt-regexp
(rx bol (* nonl)
(group (regexp (regexp-opt password-word-equivalents)))
- (* nonl) ":" (? "\^@") (* space))
+ (* nonl) ":" (? "\^@") (* blank))
"Regexp matching password-like prompts.
The regexp should match at end of buffer.
(defcustom tramp-yesno-prompt-regexp
(rx "Are you sure you want to continue connecting (yes/no"
(? "/[fingerprint]") ")?"
- (* space))
+ (* blank))
"Regular expression matching all yes/no queries which need to be confirmed.
The confirmation should be done with yes or no.
The regexp should match at end of buffer.
(defcustom tramp-yn-prompt-regexp
(rx (| "Store key in cache? (y/n)"
"Update cached key? (y/n, Return cancels connection)")
- (* space))
+ (* blank))
"Regular expression matching all y/n queries which need to be confirmed.
The confirmation should be done with y or n.
The regexp should match at end of buffer.
(defcustom tramp-terminal-prompt-regexp
(rx (| (: "TERM = (" (* nonl) ")")
(: "Terminal type? [" (* nonl) "]"))
- (* space))
+ (* blank))
"Regular expression matching all terminal setting prompts.
The regexp should match at end of buffer.
The answer will be provided by `tramp-action-terminal', which see."
:type 'regexp)
(defcustom tramp-operation-not-permitted-regexp
- (rx (| (: "preserving times" (* nonl)) "set mode") ":" (* space)
+ (rx (| (: "preserving times" (* nonl)) "set mode") ":" (* blank)
"Operation not permitted")
"Regular expression matching keep-date problems in (s)cp operations.
Copying has been performed successfully already, so this message can
"Permission denied"
"is a directory"
"not a regular file")
- (* space))
+ (* blank))
"Regular expression matching copy problems in (s)cp operations."
:type 'regexp)
"Regexp matching delimiter between method and user or host names.
Derived from `tramp-postfix-method-format'.")
-(defconst tramp-user-regexp (rx (+ (not (any "/:|" space))))
+(defconst tramp-user-regexp (rx (+ (not (any "/:|" blank))))
"Regexp matching user names.")
(defconst tramp-prefix-domain-format "%"
(defconst tramp-debug-outline-regexp
(rx ;; Timestamp.
- (+ digit) ":" (+ digit) ":" (+ digit) "." (+ digit) space
+ (+ digit) ":" (+ digit) ":" (+ digit) "." (+ digit) blank
;; Thread.
- (? (group "#<thread " (+ nonl) ">") space)
+ (? (group "#<thread " (+ nonl) ">") blank)
;; Function name, verbosity.
(+ (any "-" alnum)) " (" (group (+ digit)) ") #")
"Used for highlighting Tramp debug buffers in `outline-mode'.")
(tramp-get-default-directory (process-buffer (nth 0 args)))))
;; VEC.
((member operation
- '(tramp-get-home-directory
- tramp-get-remote-gid tramp-get-remote-uid))
+ '(tramp-get-home-directory tramp-get-remote-gid
+ tramp-get-remote-groups tramp-get-remote-uid))
(tramp-make-tramp-file-name (nth 0 args)))
;; Unknown file primitive.
(t (error "Unknown file I/O primitive: %s" operation))))
(let (result
(regexp
(rx bol (group (regexp tramp-host-regexp))
- (? (+ space) (group (regexp tramp-user-regexp))))))
+ (? (+ blank) (group (regexp tramp-user-regexp))))))
(when (re-search-forward regexp (line-end-position) t)
(setq result (append (list (match-string 2) (match-string 1)))))
(forward-line 1)
"Return a (user host) tuple allowed to access.
User is always nil."
(tramp-parse-group
- (rx (| (: bol (* space) "Host")
+ (rx (| (: bol (* blank) "Host")
(: bol (+ nonl)) ;; ???
(group (regexp tramp-host-regexp))))
- 1 (rx space)))
+ 1 (rx blank)))
;; Generic function.
(defun tramp-parse-shostkeys-sknownhosts (dirname regexp)
User is always nil."
(tramp-parse-group
(rx bol (group (| (regexp tramp-ipv6-regexp) (regexp tramp-host-regexp))))
- 1 (rx space)))
+ 1 (rx blank)))
(defun tramp-parse-passwd (filename)
"Return a list of (user host) tuples allowed to access.
(defun tramp-ps-time ()
"Read printed time oif \"ps\" in format \"[[DD-]hh:]mm:ss\".
Return it as number of seconds. Used in `tramp-process-attributes-ps-format'."
- (search-forward-regexp (rx (+ space)))
+ (search-forward-regexp (rx (+ blank)))
(search-forward-regexp (rx (? (? (group (+ digit)) "-")
(group (+ digit)) ":")
(group (+ digit)) ":"
(cond
((eq (cdr elt) 'number) (read (current-buffer)))
((eq (cdr elt) 'string)
- (search-forward-regexp (rx (+ (not space))))
+ (search-forward-regexp (rx (+ (not blank))))
(match-string 0))
((numberp (cdr elt))
- (search-forward-regexp (rx (+ space)))
+ (search-forward-regexp (rx (+ blank)))
(search-forward-regexp
(rx (+ nonl)) (+ (point) (cdr elt)))
(string-trim (match-string 0)))
((fboundp (cdr elt))
(funcall (cdr elt)))
((null (cdr elt))
- (search-forward-regexp (rx (+ whitespace)))
+ (search-forward-regexp (rx (+ blank)))
(buffer-substring (point) (line-end-position)))))
res))
;; `nice' could be `-'.
(defun tramp-handle-shell-command (command &optional output-buffer error-buffer)
"Like `shell-command' for Tramp files."
- (let* ((asynchronous (string-match-p (rx (* space) "&" (* space) eos) command))
+ (let* ((asynchronous (string-match-p (rx (* blank) "&" (* blank) eos) command))
(command (substring command 0 asynchronous))
current-buffer-p
(output-buffer-p output-buffer)
((eq ?s access) 3)))
(file-attr (file-attributes (tramp-make-tramp-file-name vec)))
(remote-uid (tramp-get-remote-uid vec 'integer))
- (remote-gid (tramp-get-remote-gid vec 'integer)))
+ (remote-gid (tramp-get-remote-gid vec 'integer))
+ (remote-groups (tramp-get-remote-groups vec 'integer)))
(or
;; Not a symlink.
(eq t (file-attribute-type file-attr))
(equal remote-gid tramp-unknown-id-integer)
(equal remote-gid (file-attribute-group-id file-attr))
(equal tramp-unknown-id-integer
- (file-attribute-group-id file-attr)))))))
+ (file-attribute-group-id file-attr))))
+ ;; Group accessible and owned by user's secondary group.
+ (and
+ (eq access
+ (aref (file-attribute-modes file-attr) (+ offset 3)))
+ (member (file-attribute-group-id file-attr) remote-groups)))))
(defmacro tramp-convert-file-attributes (vec localname id-format attr)
"Convert `file-attributes' ATTR generated Tramp backend functions.
(and (equal id-format 'integer) tramp-unknown-id-integer)
(and (equal id-format 'string) tramp-unknown-id-string)))
+(defun tramp-get-remote-groups (vec id-format)
+ "The list of groups of the remote connection VEC, in ID-FORMAT.
+ID-FORMAT valid values are `string' and `integer'."
+ (or (and (tramp-file-name-p vec)
+ (with-tramp-connection-property vec (format "groups-%s" id-format)
+ (tramp-file-name-handler #'tramp-get-remote-groups vec id-format)))
+ ;; Ensure there is a valid result.
+ (and (equal id-format 'integer) (list tramp-unknown-id-integer))
+ (and (equal id-format 'string) (list tramp-unknown-id-string))))
+
(defun tramp-local-host-p (vec)
"Return t if this points to the local host, nil otherwise.
This handles also chrooted environments, which are not regarded as local."
(goto-char (point-min))
(should
(looking-at-p
- (rx bol (+ nonl) space (literal tramp-archive-test-archive) eol))))
+ (rx bol (+ nonl) blank (literal tramp-archive-test-archive) eol))))
(with-temp-buffer
(insert-directory
(file-name-as-directory tramp-archive-test-archive)
(rx-to-string
`(:
;; There might be a summary line.
- (? "total" (+ nonl) (+ digit) (? space)
+ (? "total" (+ nonl) (+ digit) (? blank)
(? (any "EGKMPTYZk")) (? "i") (? "B") "\n")
;; We don't know in which order the files appear.
(= ,(length (directory-files tramp-archive-test-archive))
- (+ nonl) space
+ (+ nonl) blank
(regexp
,(regexp-opt (directory-files tramp-archive-test-archive)))
(? " ->" (+ nonl)) "\n"))))))
(insert-directory tmp-name1 "-al")
(goto-char (point-min))
(should
- (looking-at-p (rx bol (+ nonl) space (literal tmp-name1) eol))))
+ (looking-at-p (rx bol (+ nonl) blank (literal tmp-name1) eol))))
(with-temp-buffer
(insert-directory (file-name-as-directory tmp-name1) "-al")
(goto-char (point-min))
(should
(looking-at-p
- (rx bol (+ nonl) space (literal tmp-name1) "/" eol))))
+ (rx bol (+ nonl) blank (literal tmp-name1) "/" eol))))
(with-temp-buffer
(insert-directory
(file-name-as-directory tmp-name1) "-al" nil 'full-directory-p)
(rx-to-string
`(:
;; There might be a summary line.
- (? "total" (+ nonl) (+ digit) (? space)
+ (? "total" (+ nonl) (+ digit) (? blank)
(? (any "EGKMPTYZk")) (? "i") (? "B") "\n")
;; We don't know in which order ".", ".." and "foo" appear.
(= ,(length (directory-files tmp-name1))
- (+ nonl) space
+ (+ nonl) blank
(regexp ,(regexp-opt (directory-files tmp-name1)))
(? " ->" (+ nonl)) "\n"))))))