1e0a2b6dfSmrg#!/usr/bin/env perl 204b94745Smrg# $XTermId: paste64.pl,v 1.14 2018/11/20 01:05:55 tom Exp $ 320d2c4d2Smrg# ----------------------------------------------------------------------------- 420d2c4d2Smrg# this file is part of xterm 5d522f475Smrg# 6f2e35a3aSmrg# Copyright 2006-2014,2018 by Thomas E. Dickey 701037d57Smrg# 820d2c4d2Smrg# All Rights Reserved 901037d57Smrg# 1020d2c4d2Smrg# Permission is hereby granted, free of charge, to any person obtaining a 1120d2c4d2Smrg# copy of this software and associated documentation files (the 1220d2c4d2Smrg# "Software"), to deal in the Software without restriction, including 1320d2c4d2Smrg# without limitation the rights to use, copy, modify, merge, publish, 1420d2c4d2Smrg# distribute, sublicense, and/or sell copies of the Software, and to 1520d2c4d2Smrg# permit persons to whom the Software is furnished to do so, subject to 1620d2c4d2Smrg# the following conditions: 1701037d57Smrg# 1820d2c4d2Smrg# The above copyright notice and this permission notice shall be included 1920d2c4d2Smrg# in all copies or substantial portions of the Software. 2001037d57Smrg# 2120d2c4d2Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2220d2c4d2Smrg# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2320d2c4d2Smrg# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 2420d2c4d2Smrg# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 2520d2c4d2Smrg# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2620d2c4d2Smrg# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2720d2c4d2Smrg# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2801037d57Smrg# 2920d2c4d2Smrg# Except as contained in this notice, the name(s) of the above copyright 3020d2c4d2Smrg# holders shall not be used in advertising or otherwise to promote the 3120d2c4d2Smrg# sale, use or other dealings in this Software without prior written 3220d2c4d2Smrg# authorization. 3320d2c4d2Smrg# ----------------------------------------------------------------------------- 34d522f475Smrg# Test the paste64 option of xterm. 35d522f475Smrg 36d522f475Smrguse strict; 37e0a2b6dfSmrguse warnings; 38e0a2b6dfSmrg 39d522f475Smrguse Term::ReadKey; 40d522f475Smrguse IO::Handle; 41d522f475Smrguse MIME::Base64; 42d522f475Smrg 43d522f475Smrgour $target = ""; 44d522f475Smrg 45d522f475Smrgsub to_hex($) { 4601037d57Smrg my $value = $_[0]; 4701037d57Smrg my $result = ""; 4801037d57Smrg my $n; 4901037d57Smrg 5001037d57Smrg for ( $n = 0 ; $n < length($value) ; ++$n ) { 5101037d57Smrg $result .= sprintf( "%02X", ord substr( $value, $n, 1 ) ); 5201037d57Smrg } 5301037d57Smrg return $result; 54d522f475Smrg} 55d522f475Smrg 56d522f475Smrgsub show_string($) { 5701037d57Smrg my $value = $_[0]; 5801037d57Smrg my $n; 5901037d57Smrg 6001037d57Smrg my $result = ""; 6101037d57Smrg for ( $n = 0 ; $n < length($value) ; $n += 1 ) { 6201037d57Smrg my $c = ord substr( $value, $n, 1 ); 6301037d57Smrg if ( $c == ord '\\' ) { 6401037d57Smrg $result .= "\\\\"; 6501037d57Smrg } 6601037d57Smrg elsif ( $c == 0x1b ) { 6701037d57Smrg $result .= "\\E"; 6801037d57Smrg } 6901037d57Smrg elsif ( $c == 0x7f ) { 7001037d57Smrg $result .= "^?"; 7101037d57Smrg } 7201037d57Smrg elsif ( $c == 32 ) { 7301037d57Smrg $result .= "\\s"; 7401037d57Smrg } 7501037d57Smrg elsif ( $c < 32 ) { 7601037d57Smrg $result .= sprintf( "^%c", $c + 64 ); 7701037d57Smrg } 7801037d57Smrg elsif ( $c > 128 ) { 7901037d57Smrg $result .= sprintf( "\\%03o", $c ); 8001037d57Smrg } 8101037d57Smrg else { 8201037d57Smrg $result .= chr($c); 8301037d57Smrg } 8401037d57Smrg } 8501037d57Smrg 8601037d57Smrg printf "%s\r\n", $result; 87d522f475Smrg} 88d522f475Smrg 89d522f475Smrgsub get_reply($) { 9001037d57Smrg my $command = $_[0]; 9101037d57Smrg my $reply = ""; 9201037d57Smrg 9301037d57Smrg printf "send: "; 9401037d57Smrg show_string($command); 9501037d57Smrg 9601037d57Smrg print STDOUT $command; 9701037d57Smrg autoflush STDOUT 1; 9801037d57Smrg while (1) { 9901037d57Smrg my $test = ReadKey 1; 10001037d57Smrg last if not defined $test; 10101037d57Smrg 10201037d57Smrg #printf "%d:%s\r\n", length($reply), to_hex($test); 10301037d57Smrg $reply .= $test; 10401037d57Smrg } 10501037d57Smrg return $reply; 106d522f475Smrg} 107d522f475Smrg 108d522f475Smrgsub get_paste() { 10901037d57Smrg my $reply = get_reply( "\x1b]52;" . $target . ";?\x1b\\" ); 110d522f475Smrg 11101037d57Smrg printf "read: "; 11201037d57Smrg show_string($reply); 113d522f475Smrg 11401037d57Smrg my $data = $reply; 11501037d57Smrg $data =~ s/^\x1b]52;[[:alnum:]]*;//; 11601037d57Smrg $data =~ s/\x1b\\$//; 11701037d57Smrg printf "chop: "; 11801037d57Smrg show_string($data); 119d522f475Smrg 12001037d57Smrg $data = decode_base64($data); 12101037d57Smrg printf "data: "; 12201037d57Smrg show_string($data); 123d522f475Smrg} 124d522f475Smrg 125d522f475Smrgsub put_paste() { 12601037d57Smrg ReadMode 1; 127d522f475Smrg 12801037d57Smrg printf "data: "; 12901037d57Smrg my $data = ReadLine 0; 13001037d57Smrg chomp $data; 13101037d57Smrg ReadMode 5; 132d522f475Smrg 13301037d57Smrg $data = encode_base64($data); 13401037d57Smrg chomp $data; 13501037d57Smrg printf "data: "; 13601037d57Smrg show_string($data); 137d522f475Smrg 13801037d57Smrg my $send = "\x1b]52;" . $target . ";" . $data . "\x1b\\"; 139d522f475Smrg 14001037d57Smrg printf "send: "; 14101037d57Smrg show_string($send); 14201037d57Smrg print STDOUT $send; 14301037d57Smrg autoflush STDOUT 1; 144d522f475Smrg} 145d522f475Smrg 146d522f475Smrgsub set_target() { 14701037d57Smrg ReadMode 1; 148d522f475Smrg 14901037d57Smrg printf "target: "; 15001037d57Smrg $target = ReadLine 0; 151f2e35a3aSmrg $target =~ s/[^cps01234567]//g; 15201037d57Smrg ReadMode 5; 15301037d57Smrg printf "result: %s\r\n", $target; 154d522f475Smrg} 155d522f475Smrg 15601037d57SmrgReadMode 5, 'STDIN'; # allow single-character inputs 157d522f475Smrgwhile (1) { 15801037d57Smrg my $cmd; 15901037d57Smrg 16001037d57Smrg printf "\r\nCommand (? for help):"; 16101037d57Smrg $cmd = ReadKey 0; 16201037d57Smrg if ( $cmd eq "?" ) { 16301037d57Smrg printf "\r\np=put selection," 16401037d57Smrg . " g=get selection," 16501037d57Smrg . " q=quit," 16601037d57Smrg . " r=reset target," 16701037d57Smrg . " s=set target\r\n"; 16801037d57Smrg } 16901037d57Smrg elsif ( $cmd eq "p" ) { 17001037d57Smrg printf " ...put selection\r\n"; 17101037d57Smrg put_paste(); 17201037d57Smrg } 17301037d57Smrg elsif ( $cmd eq "g" ) { 17401037d57Smrg printf " ...get selection\r\n"; 17501037d57Smrg get_paste(); 17601037d57Smrg } 17701037d57Smrg elsif ( $cmd eq "q" ) { 17801037d57Smrg printf " ...quit\r\n"; 17901037d57Smrg last; 18001037d57Smrg } 18101037d57Smrg elsif ( $cmd eq "r" ) { 18201037d57Smrg printf " ...reset\r\n"; 18301037d57Smrg $target = ""; 18401037d57Smrg } 18501037d57Smrg elsif ( $cmd eq "s" ) { 18601037d57Smrg printf " ...set target\r\n"; 18701037d57Smrg set_target(); 18801037d57Smrg } 189d522f475Smrg} 19001037d57SmrgReadMode 0, 'STDIN'; # Reset tty mode before exiting 191