Imported Upstream version 3.3.3
[debian/amanda] / perl / Amanda / Curinfo.pm
1 # Copyright (c) 2010-2012 Zmanda, Inc.  All Rights Reserved.
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 # or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 # for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18 # Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19
20 package Amanda::Curinfo;
21
22 use strict;
23 use warnings;
24 use Carp;
25 use File::Copy;
26 use File::Path qw( mkpath );
27
28 use Amanda::Debug qw( :logging );
29 use Amanda::Util qw( sanitise_filename );
30
31 use Amanda::Curinfo::Info;
32
33 =head1 NAME
34
35 Amanda::Curinfo - Perl extension for representing the curinfo database
36
37 =head1 SYNOPSIS
38
39    use Amanda::Curinfo;
40    use Amanda::Curinfo::Info;
41
42    ...
43
44    my $ci = Amanda::Curinfo->new($somedir);
45    my $info = $ci->get_info($host, $disk);
46
47    ...
48
49    $ci->put_info($host, $disk, $newinfo);
50
51    ...
52
53    $ci->del_info($oldhost, $olddisk);
54
55 =head1 DESCRIPTION
56
57 C<Amanda::Curinfo> is a pure perl implementation of the older infofile
58 libraries.
59
60 This package manages a directory of files, referred to in the code as
61 an C<$infodir>, that contain dump data.  Each of these files is stored
62 in a nested directory structure by its host and disk name.  These
63 files can be accessed and modified using the provided functions with
64 the help of the L<Amanda::Curinfo::Info> class.
65
66 Note that this terminology is slightly different from the older
67 infofile.h implementation.  Users with no experience with infofile.h
68 can skip to the interface section.
69
70 In the API for infofile.h, the term C<infofile> actually refers a
71 directory.  This directory is called an C<infodir> within the
72 infofile.c code.  This directory held text files, which are referred
73 to as both C<infofile> and C<txinfofile> internally to infofile.c.
74
75 This rewrite simplifies the terminology by referring to the storage
76 directory as an C<$infodir> and an individual data-storing file as a
77 C<$infofile>.
78
79 =head1 INTERFACE
80
81
82 C<Amanda::Curinfo> is an interface to retrieve and store info files
83 regarding the backup history of DLEs.
84
85 C<Amanda::Curinfo> provides three major routines for handling info
86 file data.
87
88 The C<Amanda::Curinfo> constructor is pretty straightforward:
89
90    my $ci = Amanda::Curinfo->new($infodir);
91
92 Where C<$infodir> is a directory.  In order to retrieve a previously
93 stored info file if the host and disk are known, one can use
94
95    my $info = $ci->get_info($host, $disk);
96
97 Once the structure has been updated, it may be re-written to the
98 database in a similar fashion:
99
100   $ci->put_info($host, $disk, $info);
101
102 If one would like to erase an existing info entry in an infodir, the
103 usage is the same as retrieving an info object.
104
105   $ci->del_info($host, $disk);
106
107 To create a new info object, please see the documentation for
108 L<Amanda::Curinfo::Info>.
109
110 =head1 SEE ALSO
111
112 This module is meant to replicate the behavior of the library
113 described in server-src/infofile.h.  If anyone notices any major
114 problems, please report them.
115
116 =head1 AUTHOR
117
118 Paul C. Mantz E<lt>pcmantz@zmanda.comE<gt>
119
120 =cut
121
122
123 sub new
124 {
125     my ($class, $infodir) = @_;
126
127     (defined $infodir)
128       || croak("error: infodir not provided to Amanda::Curinfo");
129
130     my $self = { infodir => $infodir };
131
132     bless $self, $class;
133     return $self;
134 }
135
136 sub get_info
137 {
138     my ($self, $host, $disk) = @_;
139
140     my $infodir  = $self->{infodir};
141     my $host_q   = sanitise_filename($host);
142     my $disk_q   = sanitise_filename($disk);
143     my $infofile = "$infodir/$host_q/$disk_q/info";
144
145     return Amanda::Curinfo::Info->new($infofile);
146 }
147
148 sub put_info
149 {
150     my ($self, $host, $disk, $info) = @_;
151
152     my $infodir     = $self->{infodir};
153     my $host_q      = sanitise_filename($host);
154     my $disk_q      = sanitise_filename($disk);
155     my $infofiledir = "$infodir/$host_q/$disk_q";
156     my $infofile    = "$infofiledir/info";
157     my $infofile_tmp = "$infofile.tmp";
158
159     if (-e $infofile) {
160         copy($infofile, $infofile_tmp)
161           || croak "error: couldn't back up $infofile";
162     } elsif (!-d $infofiledir) {
163         mkpath($infofiledir)
164           || croak "error: couldn't make path $infofiledir";
165     }
166
167     my $restore = sub {
168         if (-e $infofile_tmp) {
169             copy($infofile_tmp, $infofile)
170               || croak
171               "error: couldn't restore infofile from backup $infofile_tmp";
172             unlink $infofile_tmp;
173         }
174         croak "error encountered when writing info to $infofile";
175     };
176
177     $info->write_to_file($infofile) || $restore->();
178     unlink $infofile_tmp if -e $infofile_tmp;
179     return 1;
180 }
181
182 sub del_info
183 {
184     my ($self, $host, $disk) = @_;
185
186     my $infodir  = $self->{infodir};
187     my $host_q   = sanitise_filename($host);
188     my $disk_q   = sanitise_filename($disk);
189     my $infofile = "$infodir/$host_q/$disk_q/info";
190
191     return unlink $infofile;
192 }
193
194 1;