diff options
| author | Michael Albinus | 2020-01-09 13:41:10 +0100 |
|---|---|---|
| committer | Michael Albinus | 2020-01-09 13:41:10 +0100 |
| commit | 17cfd708575c351d030f8b05c5921d1867028d79 (patch) | |
| tree | 77497c77d9932171fb6ad8218a0a0ecf7c49b7b5 | |
| parent | 70873074a15edbc64993f68d7cc50d2f46cc796b (diff) | |
| download | emacs-17cfd708575c351d030f8b05c5921d1867028d79.tar.gz emacs-17cfd708575c351d030f8b05c5921d1867028d79.zip | |
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.
| -rw-r--r-- | lisp/net/tramp-sh.el | 124 |
1 files changed, 105 insertions, 19 deletions
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 6cd299ac19c..6e5b9d243fb 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -866,8 +866,12 @@ Escape sequence %s is replaced with name of Perl binary.") | |||
| 866 | "Perl program to use for decoding a file. | 866 | "Perl program to use for decoding a file. |
| 867 | Escape sequence %s is replaced with name of Perl binary.") | 867 | Escape sequence %s is replaced with name of Perl binary.") |
| 868 | 868 | ||
| 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 | |||
| 869 | (defconst tramp-awk-encode | 873 | (defconst tramp-awk-encode |
| 870 | "od -v -t x1 -A n | busybox awk '\\ | 874 | "%a '\\ |
| 871 | BEGIN { | 875 | BEGIN { |
| 872 | b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\" | 876 | b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\" |
| 873 | b16 = \"0123456789abcdef\" | 877 | b16 = \"0123456789abcdef\" |
| @@ -897,11 +901,25 @@ END { | |||
| 897 | } | 901 | } |
| 898 | printf tail | 902 | printf tail |
| 899 | }'" | 903 | }'" |
| 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. | ||
| 901 | This string is passed to `format', so percent characters need to be doubled.") | 919 | This string is passed to `format', so percent characters need to be doubled.") |
| 902 | 920 | ||
| 903 | (defconst tramp-awk-decode | 921 | (defconst tramp-awk-decode |
| 904 | "busybox awk '\\ | 922 | "%a '\\ |
| 905 | BEGIN { | 923 | BEGIN { |
| 906 | b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\" | 924 | b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\" |
| 907 | } | 925 | } |
| @@ -926,12 +944,6 @@ BEGIN { | |||
| 926 | "Awk program to use for decoding a file. | 944 | "Awk program to use for decoding a file. |
| 927 | This string is passed to `format', so percent characters need to be doubled.") | 945 | This string is passed to `format', so percent characters need to be doubled.") |
| 928 | 946 | ||
| 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 | |||
| 935 | (defconst tramp-vc-registered-read-file-names | 947 | (defconst tramp-vc-registered-read-file-names |
| 936 | "echo \"(\" | 948 | "echo \"(\" |
| 937 | while read file; do | 949 | while read file; do |
| @@ -4401,7 +4413,7 @@ and end of region, and are expected to replace the region contents | |||
| 4401 | with the encoded or decoded results, respectively.") | 4413 | with the encoded or decoded results, respectively.") |
| 4402 | 4414 | ||
| 4403 | (defconst tramp-remote-coding-commands | 4415 | (defconst tramp-remote-coding-commands |
| 4404 | `((b64 "base64" "base64 -d -i") | 4416 | '((b64 "base64" "base64 -d -i") |
| 4405 | ;; "-i" is more robust with older base64 from GNU coreutils. | 4417 | ;; "-i" is more robust with older base64 from GNU coreutils. |
| 4406 | ;; However, I don't know whether all base64 versions do supports | 4418 | ;; However, I don't know whether all base64 versions do supports |
| 4407 | ;; this option. | 4419 | ;; this option. |
| @@ -4412,8 +4424,9 @@ with the encoded or decoded results, respectively.") | |||
| 4412 | (b64 "recode data..base64" "recode base64..data") | 4424 | (b64 "recode data..base64" "recode base64..data") |
| 4413 | (b64 tramp-perl-encode-with-module tramp-perl-decode-with-module) | 4425 | (b64 tramp-perl-encode-with-module tramp-perl-decode-with-module) |
| 4414 | (b64 tramp-perl-encode tramp-perl-decode) | 4426 | (b64 tramp-perl-encode tramp-perl-decode) |
| 4415 | ;; This is painful slow, so we put it on the end. | 4427 | ;; These are painfully slow, so we put them on the end. |
| 4416 | (b64 tramp-awk-encode tramp-awk-decode ,tramp-awk-coding-test) | 4428 | (b64 tramp-hexdump-awk-encode tramp-awk-decode) |
| 4429 | (b64 tramp-od-awk-encode tramp-awk-decode) | ||
| 4417 | (uu "uuencode xxx" "uudecode -o /dev/stdout" "test -c /dev/stdout") | 4430 | (uu "uuencode xxx" "uudecode -o /dev/stdout" "test -c /dev/stdout") |
| 4418 | (uu "uuencode xxx" "uudecode -o -") | 4431 | (uu "uuencode xxx" "uudecode -o -") |
| 4419 | (uu "uuencode xxx" "uudecode -p") | 4432 | (uu "uuencode xxx" "uudecode -p") |
| @@ -4439,6 +4452,8 @@ Perl or Shell implementation for this functionality. This | |||
| 4439 | program will be transferred to the remote host, and it is | 4452 | program will be transferred to the remote host, and it is |
| 4440 | available as shell function with the same name. A \"%t\" format | 4453 | available as shell function with the same name. A \"%t\" format |
| 4441 | specifier in the variable value denotes a temporary file. | 4454 | 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. | ||
| 4442 | 4457 | ||
| 4443 | The optional TEST command can be used for further tests, whether | 4458 | The optional TEST command can be used for further tests, whether |
| 4444 | ENCODING and DECODING are applicable.") | 4459 | ENCODING and DECODING are applicable.") |
| @@ -4489,11 +4504,6 @@ Goes through the list `tramp-local-coding-commands' and | |||
| 4489 | vec 5 "Checking remote test command `%s'" rem-test) | 4504 | vec 5 "Checking remote test command `%s'" rem-test) |
| 4490 | (unless (tramp-send-command-and-check vec rem-test t) | 4505 | (unless (tramp-send-command-and-check vec rem-test t) |
| 4491 | (throw 'wont-work-remote nil))) | 4506 | (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)) | ||
| 4497 | ;; Check if remote encoding and decoding commands can be | 4507 | ;; Check if remote encoding and decoding commands can be |
| 4498 | ;; called remotely with null input and output. This makes | 4508 | ;; called remotely with null input and output. This makes |
| 4499 | ;; sure there are no syntax errors and the command is really | 4509 | ;; sure there are no syntax errors and the command is really |
| @@ -4503,10 +4513,36 @@ Goes through the list `tramp-local-coding-commands' and | |||
| 4503 | ;; redirecting "mimencode" output to /dev/null, then as root | 4513 | ;; redirecting "mimencode" output to /dev/null, then as root |
| 4504 | ;; it might change the permissions of /dev/null! | 4514 | ;; it might change the permissions of /dev/null! |
| 4505 | (unless (stringp rem-enc) | 4515 | (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)) | ||
| 4507 | (while (string-match "-" name) | 4534 | (while (string-match "-" name) |
| 4508 | (setq name (replace-match "_" nil t name))) | 4535 | (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) | ||
| 4510 | (setq rem-enc name))) | 4546 | (setq rem-enc name))) |
| 4511 | (tramp-message | 4547 | (tramp-message |
| 4512 | vec 5 | 4548 | vec 5 |
| @@ -4521,6 +4557,15 @@ Goes through the list `tramp-local-coding-commands' and | |||
| 4521 | tmpfile) | 4557 | tmpfile) |
| 4522 | (while (string-match "-" name) | 4558 | (while (string-match "-" name) |
| 4523 | (setq name (replace-match "_" nil t name))) | 4559 | (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))) | ||
| 4524 | (when (string-match-p "\\(^\\|[^%]\\)%t" value) | 4569 | (when (string-match-p "\\(^\\|[^%]\\)%t" value) |
| 4525 | (setq tmpfile | 4570 | (setq tmpfile |
| 4526 | (make-temp-name | 4571 | (make-temp-name |
| @@ -5787,6 +5832,47 @@ ID-FORMAT valid values are `string' and `integer'." | |||
| 5787 | tramp-unknown-id-string) | 5832 | tramp-unknown-id-string) |
| 5788 | (t res))))) | 5833 | (t res))))) |
| 5789 | 5834 | ||
| 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 | |||
| 5790 | (defun tramp-get-env-with-u-option (vec) | 5876 | (defun tramp-get-env-with-u-option (vec) |
| 5791 | "Check, whether the remote `env' command supports the -u option." | 5877 | "Check, whether the remote `env' command supports the -u option." |
| 5792 | (with-tramp-connection-property vec "env-u-option" | 5878 | (with-tramp-connection-property vec "env-u-option" |