@@ -866,8 +866,12 @@ Escape sequence %s is replaced with name of Perl binary.")
866866 "Perl program to use for decoding a file.
867867Escape sequence %s is replaced with name of Perl binary.")
868868
869+ (defconst tramp-hexdump-encode "%h -v -e '16/1 \" %%02x\" \"\\n\"'"
870+ "`hexdump' program to use for encoding a file.
871+ This string is passed to `format', so percent characters need to be doubled.")
872+
869873(defconst tramp-awk-encode
870- "od -v -t x1 -A n | busybox awk '\\
874+ "%a '\\
871875BEGIN {
872876 b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
873877 b16 = \"0123456789abcdef\"
@@ -897,11 +901,25 @@ END {
897901 }
898902 printf tail
899903}'"
900- "Awk program to use for encoding a file.
904+ "`awk' program to use for encoding a file.
905+ This string is passed to `format', so percent characters need to be doubled.")
906+
907+ (defconst tramp-hexdump-awk-encode
908+ (format "%s | %s" tramp-hexdump-encode tramp-awk-encode)
909+ "`hexdump' / `awk' pipe to use for encoding a file.
910+ This string is passed to `format', so percent characters need to be doubled.")
911+
912+ (defconst tramp-od-encode "%o -v -t x1 -A n"
913+ "`od' program to use for encoding a file.
914+ This string is passed to `format', so percent characters need to be doubled.")
915+
916+ (defconst tramp-od-awk-encode
917+ (format "%s | %s" tramp-od-encode tramp-awk-encode)
918+ "`od' / `awk' pipe to use for encoding a file.
901919This string is passed to `format', so percent characters need to be doubled.")
902920
903921(defconst tramp-awk-decode
904- "busybox awk '\\
922+ "%a '\\
905923BEGIN {
906924 b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
907925}
@@ -926,12 +944,6 @@ BEGIN {
926944 "Awk program to use for decoding a file.
927945This string is passed to `format', so percent characters need to be doubled.")
928946
929- (defconst tramp-awk-coding-test
930- "test -c /dev/zero && \
931- od -v -t x1 -A n </dev/null && \
932- busybox awk '{}' </dev/null"
933- "Test command for checking `tramp-awk-encode' and `tramp-awk-decode'.")
934-
935947(defconst tramp-vc-registered-read-file-names
936948 "echo \"(\"
937949while read file; do
@@ -4401,7 +4413,7 @@ and end of region, and are expected to replace the region contents
44014413with the encoded or decoded results, respectively.")
44024414
44034415(defconst tramp-remote-coding-commands
4404- ` ((b64 "base64" "base64 -d -i")
4416+ ' ((b64 "base64" "base64 -d -i")
44054417 ;; "-i" is more robust with older base64 from GNU coreutils.
44064418 ;; However, I don't know whether all base64 versions do supports
44074419 ;; this option.
@@ -4412,8 +4424,9 @@ with the encoded or decoded results, respectively.")
44124424 (b64 "recode data..base64" "recode base64..data")
44134425 (b64 tramp-perl-encode-with-module tramp-perl-decode-with-module)
44144426 (b64 tramp-perl-encode tramp-perl-decode)
4415- ;; This is painful slow, so we put it on the end.
4416- (b64 tramp-awk-encode tramp-awk-decode ,tramp-awk-coding-test)
4427+ ;; These are painfully slow, so we put them on the end.
4428+ (b64 tramp-hexdump-awk-encode tramp-awk-decode)
4429+ (b64 tramp-od-awk-encode tramp-awk-decode)
44174430 (uu "uuencode xxx" "uudecode -o /dev/stdout" "test -c /dev/stdout")
44184431 (uu "uuencode xxx" "uudecode -o -")
44194432 (uu "uuencode xxx" "uudecode -p")
@@ -4439,6 +4452,8 @@ Perl or Shell implementation for this functionality. This
44394452program will be transferred to the remote host, and it is
44404453available as shell function with the same name. A \"%t\" format
44414454specifier in the variable value denotes a temporary file.
4455+ \"%a\", \"%h\" and \"%o\" format specifiers are replaced by the
4456+ respective `awk', `hexdump' and `od' commands.
44424457
44434458The optional TEST command can be used for further tests, whether
44444459ENCODING and DECODING are applicable.")
@@ -4489,11 +4504,6 @@ Goes through the list `tramp-local-coding-commands' and
44894504 vec 5 "Checking remote test command `%s'" rem-test)
44904505 (unless (tramp-send-command-and-check vec rem-test t)
44914506 (throw 'wont-work-remote nil)))
4492- ;; Check if remote perl exists when necessary.
4493- (when (and (symbolp rem-enc)
4494- (string-match-p "perl" (symbol-name rem-enc))
4495- (not (tramp-get-remote-perl vec)))
4496- (throw 'wont-work-remote nil))
44974507 ;; Check if remote encoding and decoding commands can be
44984508 ;; called remotely with null input and output. This makes
44994509 ;; sure there are no syntax errors and the command is really
@@ -4503,10 +4513,36 @@ Goes through the list `tramp-local-coding-commands' and
45034513 ;; redirecting "mimencode" output to /dev/null, then as root
45044514 ;; it might change the permissions of /dev/null!
45054515 (unless (stringp rem-enc)
4506- (let ((name (symbol-name rem-enc)))
4516+ (let ((name (symbol-name rem-enc))
4517+ (value (symbol-value rem-enc)))
4518+ ;; Check if remote perl exists when necessary.
4519+ (and (string-match-p "perl" name)
4520+ (not (tramp-get-remote-perl vec))
4521+ (throw 'wont-work-remote nil))
4522+ ;; Check if remote awk exists when necessary.
4523+ (and (string-match-p "\\(^\\|[^%]\\)%a" value)
4524+ (not (tramp-get-remote-awk vec))
4525+ (throw 'wont-work-remote nil))
4526+ ;; Check if remote hexdump exists when necessary.
4527+ (and (string-match-p "\\(^\\|[^%]\\)%h" value)
4528+ (not (tramp-get-remote-hexdump vec))
4529+ (throw 'wont-work-remote nil))
4530+ ;; Check if remote od exists when necessary.
4531+ (and (string-match-p "\\(^\\|[^%]\\)%o" value)
4532+ (not (tramp-get-remote-od vec))
4533+ (throw 'wont-work-remote nil))
45074534 (while (string-match "-" name)
45084535 (setq name (replace-match "_" nil t name)))
4509- (tramp-maybe-send-script vec (symbol-value rem-enc) name)
4536+ (when (string-match-p "\\(^\\|[^%]\\)%[aho]" value)
4537+ (setq value
4538+ (format-spec
4539+ value
4540+ (format-spec-make
4541+ ?a (tramp-get-remote-awk vec)
4542+ ?h (tramp-get-remote-hexdump vec)
4543+ ?o (tramp-get-remote-od vec)))
4544+ value (replace-regexp-in-string "%" "%%" value)))
4545+ (tramp-maybe-send-script vec value name)
45104546 (setq rem-enc name)))
45114547 (tramp-message
45124548 vec 5
@@ -4521,6 +4557,15 @@ Goes through the list `tramp-local-coding-commands' and
45214557 tmpfile)
45224558 (while (string-match "-" name)
45234559 (setq name (replace-match "_" nil t name)))
4560+ (when (string-match-p "\\(^\\|[^%]\\)%[aho]" value)
4561+ (setq value
4562+ (format-spec
4563+ value
4564+ (format-spec-make
4565+ ?a (tramp-get-remote-awk vec)
4566+ ?h (tramp-get-remote-hexdump vec)
4567+ ?o (tramp-get-remote-od vec)))
4568+ value (replace-regexp-in-string "%" "%%" value)))
45244569 (when (string-match-p "\\(^\\|[^%]\\)%t" value)
45254570 (setq tmpfile
45264571 (make-temp-name
@@ -5787,6 +5832,47 @@ ID-FORMAT valid values are `string' and `integer'."
57875832 tramp-unknown-id-string)
57885833 (t res)))))
57895834
5835+ (defun tramp-get-remote-busybox (vec)
5836+ "Determine remote `busybox' command."
5837+ (with-tramp-connection-property vec "busybox"
5838+ (tramp-message vec 5 "Finding a suitable `busybox' command")
5839+ (tramp-find-executable vec "busybox" (tramp-get-remote-path vec))))
5840+
5841+ (defun tramp-get-remote-awk (vec)
5842+ "Determine remote `awk' command."
5843+ (with-tramp-connection-property vec "awk"
5844+ (tramp-message vec 5 "Finding a suitable `awk' command")
5845+ (or (tramp-find-executable vec "awk" (tramp-get-remote-path vec))
5846+ (let* ((busybox (tramp-get-remote-busybox vec))
5847+ (command (format "%s %s" busybox "awk")))
5848+ (and busybox
5849+ (tramp-send-command-and-check
5850+ vec (concat command " {} </dev/null"))
5851+ command)))))
5852+
5853+ (defun tramp-get-remote-hexdump (vec)
5854+ "Determine remote `hexdump' command."
5855+ (with-tramp-connection-property vec "hexdump"
5856+ (tramp-message vec 5 "Finding a suitable `hexdump' command")
5857+ (or (tramp-find-executable vec "hexdump" (tramp-get-remote-path vec))
5858+ (let* ((busybox (tramp-get-remote-busybox vec))
5859+ (command (format "%s %s" busybox "hexdump")))
5860+ (and busybox
5861+ (tramp-send-command-and-check vec (concat command " </dev/null"))
5862+ command)))))
5863+
5864+ (defun tramp-get-remote-od (vec)
5865+ "Determine remote `od' command."
5866+ (with-tramp-connection-property vec "od"
5867+ (tramp-message vec 5 "Finding a suitable `od' command")
5868+ (or (tramp-find-executable vec "od" (tramp-get-remote-path vec))
5869+ (let* ((busybox (tramp-get-remote-busybox vec))
5870+ (command (format "%s %s" busybox "od")))
5871+ (and busybox
5872+ (tramp-send-command-and-check
5873+ vec (concat command " -A n </dev/null"))
5874+ command)))))
5875+
57905876(defun tramp-get-env-with-u-option (vec)
57915877 "Check, whether the remote `env' command supports the -u option."
57925878 (with-tramp-connection-property vec "env-u-option"
0 commit comments