19b5ce663Sespie# ex:ts=8 sw=4: 2*039cbdaaSespie# $OpenBSD: Interactive.pm,v 1.23 2023/06/13 09:07:17 espie Exp $ 39b5ce663Sespie# 41144937fSespie# Copyright (c) 2005-2007 Marc Espie <espie@openbsd.org> 59b5ce663Sespie# 69b5ce663Sespie# Permission to use, copy, modify, and distribute this software for any 79b5ce663Sespie# purpose with or without fee is hereby granted, provided that the above 89b5ce663Sespie# copyright notice and this permission notice appear in all copies. 99b5ce663Sespie# 109b5ce663Sespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 119b5ce663Sespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 129b5ce663Sespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 139b5ce663Sespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 149b5ce663Sespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 159b5ce663Sespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 169b5ce663Sespie 17*039cbdaaSespieuse v5.36; 189b5ce663Sespie 199b5ce663Sespiepackage OpenBSD::Interactive; 209b5ce663Sespie 21*039cbdaaSespiesub new($class, $state, $level) 22eb8b7390Sespie{ 23eb8b7390Sespie bless { 24eb8b7390Sespie state => $state, 25eb8b7390Sespie always => 0, 265012247cSespie level => $level, 27eb8b7390Sespie }, $class; 28eb8b7390Sespie} 29c9e26ce6Sespie 30*039cbdaaSespiesub ask_list($self, $prompt, @values) 319b5ce663Sespie{ 32eb8b7390Sespie if ($self->{always}) { 339b5ce663Sespie return $values[0]; 349b5ce663Sespie } 35bfacf0cdSespie my ($fh, $pid); 36bfacf0cdSespie if ($self->{state}->height <= @values + 1) { 37bfacf0cdSespie $pid = open($fh, "|-", "more", "-ce"); 38bfacf0cdSespie } 39eb8b7390Sespie 40bfacf0cdSespie $fh //= \*STDERR; 41bfacf0cdSespie 42bfacf0cdSespie $self->{state}->fhsay($fh, '#1', $prompt); 439b5ce663Sespie my $i = 0; 449b5ce663Sespie for my $v (@values) { 45bfacf0cdSespie $self->{state}->fhsay($fh, "#1\t#2: #3", 46eb8b7390Sespie $i == 0 ? "a" : "", $i, $v); 479b5ce663Sespie $i++; 489b5ce663Sespie } 49bfacf0cdSespie if (defined $pid) { 50bfacf0cdSespie close($fh); 51bfacf0cdSespie waitpid $pid, 0; 52bfacf0cdSespie } 539b5ce663SespieLOOP: 54eb8b7390Sespie $self->{state}->errprint("Your choice: "); 559b5ce663Sespie my $result = <STDIN>; 5639100236Sbernd unless (defined $result) { 57eb8b7390Sespie $self->{state}->errsay(""); 5839100236Sbernd return $values[0]; 5939100236Sbernd } 609b5ce663Sespie chomp $result; 619b5ce663Sespie if ($result eq '') { 629b5ce663Sespie return $values[0]; 639b5ce663Sespie } 64c9e26ce6Sespie if ($result eq 'a') { 65eb8b7390Sespie $self->{always} = 1; 66c9e26ce6Sespie return $values[0]; 67c9e26ce6Sespie } 68cc24e6f2Sespie if ($result =~ m/^\d+$/o) { 699b5ce663Sespie if ($result >= 0 && $result < @values) { 709b5ce663Sespie return $values[$result]; 719b5ce663Sespie } 72eb8b7390Sespie $self->{state}->errsay("invalid numeric value !"); 739b5ce663Sespie goto LOOP; 749b5ce663Sespie } 759b5ce663Sespie if (grep { $result eq $_ } @values) { 769b5ce663Sespie return $result; 779b5ce663Sespie } else { 78eb8b7390Sespie $self->{state}->errsay("Ambiguous value !"); 799b5ce663Sespie goto LOOP; 809b5ce663Sespie } 819b5ce663Sespie} 829b5ce663Sespie 83*039cbdaaSespiesub confirm($self, $prompt, $yesno = 0) 849b5ce663Sespie{ 85eb8b7390Sespie if ($self->{always}) { 866a938751Sespie return 1; 876a938751Sespie } 889b5ce663SespieLOOP2: 89eb8b7390Sespie $self->{state}->errprint("#1 ? [#2/a] ", 90eb8b7390Sespie $prompt, $yesno ? "Y/n" : "y/N"); 919b5ce663Sespie 929b5ce663Sespie my $result = <STDIN>; 9339100236Sbernd unless (defined $result) { 94eb8b7390Sespie $self->{state}->errsay(""); 95eb8b7390Sespie return $yesno; 9639100236Sbernd } 979b5ce663Sespie chomp $result; 98cc24e6f2Sespie $result =~ s/\s+//go; 999b5ce663Sespie $result =~ tr/A-Z/a-z/; 1009b5ce663Sespie if ($result eq 'yes' or $result eq 'y') { 1019b5ce663Sespie return 1; 1029b5ce663Sespie } 1039b5ce663Sespie if ($result eq 'no' or $result eq 'n') { 1049b5ce663Sespie return 0; 1059b5ce663Sespie } 106e78f16efSespie if ($result eq 'a') { 107eb8b7390Sespie $self->{always} = 1; 1086a938751Sespie return 1; 1096a938751Sespie } 1109b5ce663Sespie if ($result eq '') { 111eb8b7390Sespie return $yesno; 1129b5ce663Sespie } 113eb8b7390Sespie $self->{state}->errsay("Ambiguous answer"); 1149b5ce663Sespie goto LOOP2; 1159b5ce663Sespie} 1169b5ce663Sespie 117*039cbdaaSespiesub is_interactive($self) 118eb8b7390Sespie{ 119*039cbdaaSespie return $self->{level}; 120eb8b7390Sespie} 121eb8b7390Sespie 1229b5ce663Sespie1; 123