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