[pve-devel] [PATCH common 2/4] pty: add read_password helper

Wolfgang Bumiller w.bumiller at proxmox.com
Fri Nov 24 11:24:23 CET 2017


Short helper which doesn't need readline and/or deal with
history cleanup.

Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
 src/PVE/PTY.pm | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/src/PVE/PTY.pm b/src/PVE/PTY.pm
index 5f6c7a7..4067bd5 100644
--- a/src/PVE/PTY.pm
+++ b/src/PVE/PTY.pm
@@ -168,6 +168,66 @@ sub tcsetsize($$$) {
 	or die "failed to set window size: $!\n";
 }
 
+sub read_password(;$$) {
+    my ($query, $infd, $outfd) = @_;
+
+    my $password = '';
+
+    $infd //= \*STDIN;
+
+    if (!-t $infd) { # Not a terminal? Then just get a line...
+	local $/ = "\n";
+	$password = <$infd>;
+	die "EOF while reading password\n" if !defined $password;
+	chomp $password; # Chop off the newline
+	return $password;
+    }
+
+    $outfd //= \*STDOUT;
+
+    # Raw read loop:
+    my $old_termios;
+    $old_termios = tcgetattr($infd);
+    my $raw_termios = {%$old_termios};
+    cfmakeraw($raw_termios);
+    tcsetattr($infd, $raw_termios);
+    eval {
+	my $echo = undef;
+	my ($ch, $got);
+	syswrite($outfd, $query, length($query));
+	while (($got = sysread($infd, $ch, 1))) {
+	    my ($ord) = unpack('C', $ch);
+	    if ($ord == 0xD) {
+		# newline, we're done
+		syswrite($outfd, "\r\n", 2);
+		last;
+	    } elsif ($ord == 0x7f) {
+		# backspace - if it's the first key disable
+		# asterisks
+		$echo //= 0;
+		if (length($password)) {
+		    chop $password;
+		    syswrite($outfd, "\b \b", 3);
+		}
+	    } elsif ($ord == 0x09) {
+		# TAB disables the asterisk-echo
+		$echo = 0;
+	    } else {
+		# other character, append to password, if it's
+		# the first character enable asterisks echo
+		$echo //= 1;
+		$password .= $ch;
+		syswrite($outfd, '*', 1) if $echo;
+	    }
+	}
+	die "read error: $!\n" if !defined($got);
+    };
+    my $err = $@;
+    tcsetattr($infd, $old_termios);
+    die $err if $err;
+    return $password;
+}
+
 # Class functions
 
 sub new {
-- 
2.11.0





More information about the pve-devel mailing list