2b67216220e9e34e3b1cf3ea0d271e769a4c7591
[debian/amanda] / perl / Amanda / Interactivity / stdin.pm
1 # Copyright (c) 2010 Zmanda, Inc.  All Rights Reserved.
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License version 2 as published
5 # by the Free Software Foundation.
6 #
7 # This program is distributed in the hope that it will be useful, but
8 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
10 # for more details.
11 #
12 # You should have received a copy of the GNU General Public License along
13 # with this program; if not, write to the Free Software Foundation, Inc.,
14 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 #
16 # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
17 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
18
19 package Amanda::Interactivity::stdin;
20
21 use strict;
22 use warnings;
23 use POSIX qw( :errno_h );
24 use vars qw( @ISA );
25 @ISA = qw( Amanda::Interactivity );
26
27 use Amanda::Paths;
28 use Amanda::Util;
29 use Amanda::Debug qw( debug );
30 use Amanda::Changer;
31 use Amanda::MainLoop qw( :GIOCondition );
32
33 =head1 NAME
34
35 Amanda::Interactivity::stdin -- Interactivity class to read user request from stdin
36
37 =head1 SYNOPSIS
38
39 Amanda::Interactivity class to write user request on stdout and read reply
40 from stdin.
41
42 =cut
43
44 sub new {
45     my $class = shift;
46
47     my $self = {
48         input_src => undef,
49     };
50     return bless ($self, $class);
51 }
52
53 sub abort {
54     my $self = shift @_;
55
56     if ($self->{'input_src'}) {
57         $self->{'input_src'}->remove();
58         $self->{'input_src'} = undef;
59     }
60 }
61
62 sub user_request {
63     my $self = shift @_;
64     my %params = @_;
65     my $buffer = "";
66
67     my $message  = $params{'message'};
68     my $label    = $params{'label'};
69     my $err      = $params{'err'};
70     my $chg_name = $params{'chg_name'};
71
72     my $data_in = sub {
73         my $b;
74         my $n_read = POSIX::read(0, $b, 1);
75         if (!defined $n_read) {
76             return if ($! == EINTR);
77             $self->abort();
78             return $params{'request_cb'}->(
79                         Amanda::Changer::Error->new('fatal',
80                                 message => "Fail to read from stdin"));
81         } elsif ($n_read == 0) {
82             $self->abort();
83             return $params{'request_cb'}->(
84                         Amanda::Changer::Error->new('fatal',
85                                 message => "Aborted by user"));
86         } else {
87             $buffer .= $b;
88             if ($b eq "\n") {
89                 my $line = $buffer;
90                 chomp $line;
91                 $buffer = "";
92                 $self->abort();
93                 return $params{'request_cb'}->(undef, $line);
94             }
95         }
96     };
97
98     print "$err\n";
99     print "Insert volume labeled '$label' in $chg_name\n";
100     print "and press <enter> enter, or ^D to abort.\n";
101
102     $self->{'input_src'} = Amanda::MainLoop::fd_source(0, $G_IO_IN|$G_IO_HUP|$G_IO_ERR);
103     $self->{'input_src'}->set_callback($data_in);
104     return;
105 }
106
107 1;