* Moved call to NmbLookupFindHostCmd in BackupPC_dump to after the
[BackupPC.git] / bin / BackupPC_archiveHost
1 #!/bin/perl
2 #=============================================================
3 #
4 # BackupPC_archiveHost: Archive files for a single host
5 #
6 # DESCRIPTION
7 #
8 #   Usage: BackupPC_archiveHost tarCreatePath splitPath parPath host bkupNum \
9 #               compPath fileExt splitSize outLoc parFile share
10 #
11 #   This script is run for each host to create an archive.
12 #
13 #   This script is executed by BackupPC_archive, based on the setting
14 #   of $Conf{ArchiveClientCmd}.  This script can be copied and modified
15 #   for site-specific behavior.  Update $Conf{ArchiveClientCmd} to point
16 #   at your customized archive script.
17 #
18 # AUTHOR
19 #   Craig Barratt  <cbarratt@users.sourceforge.net>
20 #   Josh Marshall
21 #
22 # COPYRIGHT
23 #   Copyright (C) 2001-2007  Craig Barratt
24 #
25 #   This program is free software; you can redistribute it and/or modify
26 #   it under the terms of the GNU General Public License as published by
27 #   the Free Software Foundation; either version 2 of the License, or
28 #   (at your option) any later version.
29 #
30 #   This program is distributed in the hope that it will be useful,
31 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
32 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33 #   GNU General Public License for more details.
34 #
35 #   You should have received a copy of the GNU General Public License
36 #   along with this program; if not, write to the Free Software
37 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
38 #
39 #========================================================================
40 #
41 # Version 3.1.0, released 25 Nov 2007.
42 #
43 # See http://backuppc.sourceforge.net.
44 #
45 #========================================================================
46
47 use strict;
48 use File::Path;
49 use lib "/usr/local/BackupPC/lib";
50 use BackupPC::Lib;
51
52 #
53 # Pick up the command-line arguments
54 #
55 if ( @ARGV != 11 ) {
56     print <<EOF;
57 Usage: $0 tarCreatePath splitPath parPath host bkupNum \\
58           compPath fileExt splitSize outLoc parFile share
59 EOF
60     exit(1);
61 }
62 my $tarCreate    = $ARGV[0];
63 my $splitPath    = $ARGV[1];
64 my $parPath      = $ARGV[2];
65 my $host         = $ARGV[3];
66 my $bkupNum      = $ARGV[4];
67 my $compPath     = $ARGV[5];
68 my $fileExt      = $ARGV[6];
69 my $splitSize    = $ARGV[7];
70 my $outLoc       = $ARGV[8];
71 my $parfile      = $ARGV[9];
72 my $share        = $ARGV[10];
73
74 die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
75
76 #
77 # Make sure the specified programs are executable
78 #
79 foreach my $prog ( ($tarCreate, $compPath, $splitPath, $parPath) ) {
80     next if ( $prog eq "" || -x $prog );
81     print("Error: $prog is not an executable program\n");
82     exit(1);
83 }
84 my $mesg = "Writing tar archive for host $host, backup #$bkupNum";
85
86 #
87 # Build the command we will run
88 #
89 $share       = $bpc->shellEscape($share);
90 $host        = $bpc->shellEscape($host);
91 my $outLocE  = $bpc->shellEscape($outLoc);
92
93 #
94 # We prefer to use /bin/csh because the exit status of a pipeline
95 # is non-zero if any command is non zero.  In contrast, /bin/sh
96 # and /bin/bash use the convention that the exit status is just
97 # the exit status of the last command of the pipeline.
98 #
99 my @shell;
100 if ( -x "/bin/csh" ) {
101     @shell = ("/bin/csh", "-cf");
102 } elsif ( -x "/bin/sh" ) {
103     @shell = ("/bin/sh", "-c");
104 } else {
105     print("Error: Can't find executable /bin/csh or /bin/sh\n");
106     exit(1);
107 }
108 my $cmd = "$tarCreate -t -h $host -n $bkupNum -s $share . ";
109 $cmd   .= "| $compPath " if ( $compPath ne "cat"
110                            && $compPath ne "/bin/cat"
111                            && $compPath ne "" );
112 if ( -b $outLoc || -c $outLoc || -f $outLoc ) {
113     #
114     # Output file is a device or a regular file, so don't use split
115     #
116     $cmd  .= ">> $outLocE";
117     $mesg .= " to $outLocE";
118 } else {
119     mkpath($outLoc) if ( !-d $outLoc );
120     if ( !-d $outLoc ) {
121         print("Error: unable to create output directory $outLoc\n");
122         exit(1);
123     }
124     if ( $splitSize > 0 && -x $splitPath ) {
125         $cmd  .= "| $splitPath -b $splitSize - $outLocE/$host.$bkupNum.tar$fileExt.";
126         $mesg .= ", split to output files $outLocE/$host.$bkupNum.tar$fileExt.*";
127     } else {
128         $cmd  .= "> $outLocE/$host.$bkupNum.tar$fileExt";
129         $mesg .= " to output file $outLocE/$host.$bkupNum.tar$fileExt";
130     }
131 }
132 print("$mesg\n");
133
134 #
135 # Run the command
136 #
137 my $ret = system(@shell, $cmd);
138 if ( $ret ) {
139     print("Executing: @shell $cmd\n");
140     print("Error: $tarCreate, compress or split failed\n");
141     exit(1);
142 }
143
144 #
145 # Run optional parity file generation (only if the output is a directory,
146 # ie: not a tape device).
147 #
148 if ( -d $outLoc && -x $parPath ) {
149     if ( $parfile != 0 ) {
150         print("Running $parPath to create parity files\n");
151         my $parCmd = "$parPath c -r$parfile $outLocE/$host.$bkupNum.tar$fileExt.par2 $outLocE/$host.$bkupNum.tar$fileExt*";
152         $ret = system($parCmd);
153         if ( $ret ) {
154             print("Executing: $parCmd\n");
155             print("Error: $parPath failed\n");
156             exit(1);
157         }
158     }
159 }