Skip to content

Commit 17cfd70

Browse files
committed
Add hexdump/awk file encoding to Tramp. (Bug#35639)
* lisp/net/tramp-sh.el (tramp-hexdump-encode, tramp-hexdump-awk-encode) (tramp-od-encode, tramp-od-awk-encode): New defconst. (tramp-awk-encode, tramp-awk-decode): Adapt. (tramp-awk-coding-test): Remove. (tramp-remote-coding-commands): Add hexdump/awk encoding. (Bug#35639) (tramp-find-inline-encoding): Adapt handling of awk, hexdump and od. (tramp-get-remote-busybox, tramp-get-remote-awk) (tramp-get-remote-hexdump, tramp-get-remote-od): New defuns.
1 parent 7087307 commit 17cfd70

File tree

1 file changed

+105
-19
lines changed

1 file changed

+105
-19
lines changed

lisp/net/tramp-sh.el

Lines changed: 105 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -866,8 +866,12 @@ Escape sequence %s is replaced with name of Perl binary.")
866866
"Perl program to use for decoding a file.
867867
Escape 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 '\\
871875
BEGIN {
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.
901919
This string is passed to `format', so percent characters need to be doubled.")
902920

903921
(defconst tramp-awk-decode
904-
"busybox awk '\\
922+
"%a '\\
905923
BEGIN {
906924
b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
907925
}
@@ -926,12 +944,6 @@ BEGIN {
926944
"Awk program to use for decoding a file.
927945
This 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 \"(\"
937949
while read file; do
@@ -4401,7 +4413,7 @@ and end of region, and are expected to replace the region contents
44014413
with 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
44394452
program will be transferred to the remote host, and it is
44404453
available as shell function with the same name. A \"%t\" format
44414454
specifier 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

44434458
The optional TEST command can be used for further tests, whether
44444459
ENCODING 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

Comments
 (0)