Lots of changes:
[BackupPC.git] / makeDist
1 #!/bin/perl
2 #
3 # makeDist: Build a BackupPC distribution
4 #
5 # DESCRIPTION
6 #
7 #   This script should be run with no arguments to build a
8 #   distribution.  The $Version and $ReleaseDate should be
9 #   edited below to specify the version name and the release
10 #   date.  The distribution is createede in the sub-directory
11 #   dist.  The dsitribution is in the file name:
12 #
13 #           dist/BackupPC-$Version.tar.gz.
14 #
15 # AUTHOR
16 #   Craig Barratt <cbarratt@users.sourceforge.net>
17 #
18 # COPYRIGHT
19 #   Copyright (C) 2001-2003  Craig Barratt
20 #
21 #   This program is free software; you can redistribute it and/or modify
22 #   it under the terms of the GNU General Public License as published by
23 #   the Free Software Foundation; either version 2 of the License, or
24 #   (at your option) any later version.
25 #
26 #   This program is distributed in the hope that it will be useful,
27 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
28 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 #   GNU General Public License for more details.
30 #
31 #   You should have received a copy of the GNU General Public License
32 #   along with this program; if not, write to the Free Software
33 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34 #
35 #========================================================================
36 #
37
38 use strict;
39 use File::Path;
40 use File::Copy;
41
42 umask(0022);
43
44 my $Version     = "2.1.0_CVS";
45 my $ReleaseDate = "8 Feb 2004";
46 my $DistDir     = "dist/BackupPC-$Version";
47
48 my @PerlSrc = qw(
49     bin/BackupPC
50     bin/BackupPC_archive
51     bin/BackupPC_archiveHost
52     bin/BackupPC_dump
53     bin/BackupPC_link
54     bin/BackupPC_nightly
55     bin/BackupPC_restore
56     bin/BackupPC_sendEmail
57     bin/BackupPC_serverMesg
58     bin/BackupPC_trashClean
59     bin/BackupPC_tarExtract
60     bin/BackupPC_tarCreate
61     bin/BackupPC_compressPool
62     bin/BackupPC_zipCreate
63     bin/BackupPC_zcat
64     lib/BackupPC/Attrib.pm
65     lib/BackupPC/FileZIO.pm
66     lib/BackupPC/Lib.pm
67     lib/BackupPC/PoolWrite.pm
68     lib/BackupPC/View.pm
69     lib/BackupPC/CGI/AdminOptions.pm
70     lib/BackupPC/CGI/Archive.pm
71     lib/BackupPC/CGI/ArchiveInfo.pm
72     lib/BackupPC/CGI/Browse.pm
73     lib/BackupPC/CGI/DirHistory.pm
74     lib/BackupPC/CGI/EmailSummary.pm
75     lib/BackupPC/CGI/GeneralInfo.pm
76     lib/BackupPC/CGI/HostInfo.pm
77     lib/BackupPC/CGI/Lib.pm
78     lib/BackupPC/CGI/LOGlist.pm
79     lib/BackupPC/CGI/Queue.pm
80     lib/BackupPC/CGI/ReloadServer.pm
81     lib/BackupPC/CGI/RestoreFile.pm
82     lib/BackupPC/CGI/RestoreInfo.pm
83     lib/BackupPC/CGI/Restore.pm
84     lib/BackupPC/CGI/StartServer.pm
85     lib/BackupPC/CGI/StartStopBackup.pm
86     lib/BackupPC/CGI/StopServer.pm
87     lib/BackupPC/CGI/Summary.pm
88     lib/BackupPC/CGI/View.pm
89     lib/BackupPC/Lang/de.pm
90     lib/BackupPC/Lang/en.pm
91     lib/BackupPC/Lang/es.pm
92     lib/BackupPC/Lang/fr.pm
93     lib/BackupPC/Xfer/Archive.pm
94     lib/BackupPC/Xfer/Smb.pm
95     lib/BackupPC/Xfer/Tar.pm
96     lib/BackupPC/Xfer/Rsync.pm
97     lib/BackupPC/Xfer/RsyncFileIO.pm
98     lib/BackupPC/Zip/FileMember.pm
99     cgi-bin/BackupPC_Admin
100 );
101
102 #
103 # Check config parameters
104 #
105 my $ConfVars = {};
106 my $errCnt;
107
108 $errCnt += CheckConfigParams("conf/config.pl", $ConfVars, 0);
109 $ConfVars->{BackupPCUser} = 2;
110 $ConfVars->{CgiDir} = 2;
111 $ConfVars->{InstallDir} = 2;
112 $ConfVars->{CgiImageDir} = 2;
113 foreach my $file ( @PerlSrc ) {
114     $errCnt += CheckConfigParams($file, $ConfVars, 1);
115 }
116 $errCnt += CheckLangUsage();
117 exit(1) if ( $errCnt );
118
119 $errCnt = 0;
120 foreach my $var ( sort(keys(%$ConfVars) ) ) {
121     next if ( $ConfVars->{$var} >= 2 || $var =~ /^\$/ );
122     printf("Unused config parameter $var\n");
123     $errCnt++;
124 }
125 exit(1) if ( $errCnt );
126
127 rmtree($DistDir, 0, 0);
128 mkpath($DistDir, 0, 0777);
129
130 foreach my $dir ( qw(bin doc conf images init.d/src cgi-bin
131                      lib/BackupPC/CGI
132                      lib/BackupPC/Lang
133                      lib/BackupPC/Xfer
134                      lib/BackupPC/Zip
135                 ) ) {
136     mkpath("$DistDir/$dir", 0, 0777);
137 }
138
139 my %ConfName;
140 my $ConfPod = config2pod();
141 rmtree("doc", 0, 0);
142 mkpath("doc", 0, 0777);
143 InstallFile("doc-src/BackupPC.pod", "doc/BackupPC.pod");
144
145 use Pod::Html;
146 pod2html("doc/BackupPC.pod",
147         "--backlink=Back to Top",
148         "--header",
149         "--title=BackupPC",
150         "--outfile=doc/BackupPC.html");
151
152 foreach my $file ( (@PerlSrc,
153             <images/*>,
154             qw(
155                 conf/config.pl
156                 conf/hosts
157                 init.d/README
158                 init.d/src/debian-backuppc
159                 init.d/src/gentoo-backuppc
160                 init.d/src/gentoo-backuppc.conf
161                 init.d/src/linux-backuppc
162                 init.d/src/solaris-backuppc
163                 init.d/src/suse-backuppc
164                 doc/BackupPC.pod
165                 doc/BackupPC.html
166                 README
167                 LICENSE
168                 ChangeLog
169                 configure.pl
170         )) ) {
171     InstallFile("$file", "$DistDir/$file");
172 }
173 rmtree("doc", 0, 0);
174 system("cd dist ; tar zcf BackupPC-$Version.tar.gz BackupPC-$Version");
175 print("Distribution written to dist/BackupPC-$Version.tar.gz\n");
176 unlink("pod2htmd.x~~");
177 unlink("pod2htmi.x~~");
178
179 ###########################################################################
180 # Subroutines
181 ###########################################################################
182
183 sub InstallFile
184 {
185     my($file, $dest) = @_;
186
187     unlink($dest) if ( -d $dest );
188     if ( $file =~ /\.gif/ ) {
189         die("can't copy($file, $dest)\n") unless copy($file, $dest);
190     } else {
191         open(FILE, $file)   || die("can't open $file for reading\n");
192         open(OUT, ">$dest") || die("can't open $dest for writing\n");
193         binmode(FILE);
194         binmode(OUT);
195         while ( <FILE> ) {
196             s/^# *Version \d+\.\d+[\.\w]*, released \d+ \w+ \d{4}\.?/# Version __VERSION__, released __RELEASEDATE__./;
197             s/__VERSION__/$Version/g;
198             s/__RELEASEDATE__/$ReleaseDate/g;
199             if ( $file =~ /BackupPC\.html$/ && !/A NAME="item_%24Conf/ ) {
200                 s/\$Conf{([^}]*)}/
201                         defined($ConfName{$1})
202                             ? "<A HREF=\"#$ConfName{$1}\">\$Conf{$1}<\/A>"
203                             : "\$Conf{$1}"/eg;
204             }
205             if ( /__CONFIGPOD__/ ) {
206                 print OUT $ConfPod;
207             } elsif ( /^use lib ".*BackupPC\/lib";/
208                     || /^use lib "\/home\/pcbackup\/install\/lib";/ ) {
209                 print OUT "use lib \"__INSTALLDIR__/lib\";\n";
210             } elsif ( $file =~ /Lib.pm/ && /(.*TopDir *=> .*)'.*',/ ) {
211                 print OUT "$1'__TOPDIR__',\n";
212             } elsif ( $file =~ /Lib.pm/ && /(.*Version *=> .*)'[\w\d\.]+',/ ) {
213                 print OUT "$1'$Version',\n";
214             } elsif ( $file =~ /Lib.pm/ && /(.*BinDir *=> .*)'.*',/ ) {
215                 print OUT "$1'__INSTALLDIR__',\n";
216             } elsif ( $file =~ /Lib.pm/ && /(.*LibDir *=> .*)'.*',/ ) {
217                 print OUT "$1'__INSTALLDIR__',\n";
218             } elsif ( $file =~ /BackupPC_Admin/ && /(my *\$installDir *= *)'.*'/ ) {
219                 print OUT "$1'__INSTALLDIR__/lib';\n";
220             } else {
221                 print OUT;
222             }
223         }
224         close(FILE);
225         close(OUT);
226     }
227     if ( -x $file ) {
228         chmod(0555, $dest);
229     } else {
230         chmod(0444, $dest);
231     }
232 }
233
234 sub config2pod
235 {
236     open(C, "conf/config.pl") || die("can't open conf/config.pl");
237     binmode(C);
238     my($str, $out, $getHdr, @conf);
239     my $first = 1;
240     while ( <C> ) {
241         chomp;
242         s/ +$//;
243         if ( /^#########################/ ) {
244             if ( $getHdr ) {
245                 $str =~ s/\n.*//sg;
246                 $out .= "=back\n\n" if ( !$first );
247                 $out .= "=head2 $str\n\n=over 4\n\n";
248                 $str = "";
249                 $first = 0;
250             }
251             $getHdr = !$getHdr;
252             next;
253         }
254         if ( /^#/ ) {
255             s/# ?//;
256             next if ( $str eq "" && /^$/ );
257             $str .= $_ . "\n";
258             $str .= "\n" if ( $str =~ /examples?:\n$/i );
259         } elsif ( /^\$Conf{([^}]*)/ ) {
260             my $var = $1;
261             s/  +/ /g;
262             s/;\s*#.*/;/;
263             if ( !s/\[$/[ ... ];/ && !s/<<'EOF'/.../ ) {
264                 s/([^;])\s*$/$1 .../;
265             }
266             push(@conf, $_);
267             my $text = $_;
268             $text =~ s/\s+/_/sg;
269             $text =~ s{(\W)}{sprintf("%%%02X", ord($1) )}gxe;
270             $text = substr($text, 0, 50);
271             $ConfName{$var} = "item_$text";
272         } elsif ( /^$/ ) {
273             if ( $str ne "" && @conf ) {
274                 $out .= "=item " . join("\n\n=item ", @conf) . "\n\n";
275                 $out .= $str;
276                 $out .= "\n" if ( $str !~ /\n$/ );
277             }
278             $str = "";
279             @conf = ();
280         }
281     }
282     if ( $str ne "" && @conf ) {
283         $out .= "=item " . join("\n\n=item ", @conf) . "\n\n";
284         $out .= $str;
285         $out .= "\n" if ( $str !~ /\n$/ );
286     }
287     $out .= "=back\n\n" if ( !$first );
288     return $out;
289 }
290
291 sub CheckConfigParams
292 {
293     my($file, $vars, $check) = @_;
294     my $errors;
295
296     open(F, $file) || die("can't open $file\n");
297     binmode(F);
298     if ( $check ) {
299         while ( <F> ) {
300             s/\$(self|bpc)->{Conf}{([^}\$]+)}/if ( !defined($vars->{$2}) ) {
301                     print("Unexpected Conf var $2 in $file\n");
302                     $errors++;
303                 } else {
304                     $vars->{$2}++;
305                 }/eg;
306             s/\$[Cc]onf(?:->)?{([^}\$]+)}/if ( !defined($vars->{$1}) ) {
307                     print("Unexpected Conf var $1 in $file\n");
308                     $errors++;
309                 } else {
310                     $vars->{$1}++;
311                 }/eg;
312             s/UserCommandRun\("([^"]*)"\)/if ( !defined($vars->{$1}) ) {
313                     print("Unexpected Conf var $1 in $file\n");
314                     $errors++;
315                 } else {
316                     $vars->{$1}++;
317                 }/eg;
318         }
319     } else {
320         while ( <F> ) {
321             s/^[^#]*\$self->{Conf}{([^}]*)/$vars->{$1} = 1;/eg;
322             s/^[^#]*\$Conf{([^}]*)/$vars->{$1} = 1;/eg;
323         }
324     }
325     close(F);
326     return $errors;
327 }
328
329 #
330 # Make sure that every lang variable in cgi-bin/BackupPC_Admin matches
331 # the strings in each lib/BackupPC/Lang/*.pm file.  This makes sure
332 # we didn't miss any translations in any of the languages.
333 #
334 sub CheckLangUsage
335 {
336     my $errors;
337     my $vars = {};
338
339     foreach my $file ( (
340                 qw(cgi-bin/BackupPC_Admin bin/BackupPC_sendEmail),
341                 <lib/BackupPC/CGI/*pm>
342             ) ) {
343         open(F, $file) || die("can't open $file");
344         binmode(F);
345         while ( <F> ) {
346             s/\$Lang->{([^}]*)}/$vars->{$1} = 1;/eg;
347         }
348         close(F);
349     }
350     # CB: disable other lang checks for now
351     #
352     # foreach my $f ( <lib/BackupPC/Lang/*.pm> ) {
353     #
354     foreach my $f ( <lib/BackupPC/Lang/en.pm> ) {
355         my $done = {};
356         open(F, $f) || die("can't open $f\n");
357         binmode(F);
358         while ( <F> ) {
359             s/#.*//g;
360             s/\$Lang{([^}]*)}/
361                     my $var = $1;
362                     next if ( $var =~ m{^(Reason_|Status_|backupType_)} );
363                     if ( !defined($vars->{$var}) ) {
364                         print("Unexpected Lang var $var in $f\n");
365                         $errors++;
366                     } else {
367                         $done->{$var} = 1;
368                     }/eg;
369         }
370         close(F);
371         foreach my $v ( keys(%$vars) ) {
372             #
373             # skip "variables" with "$", since they are like expressions
374             #
375             next if ( $v =~ /\$/ );
376             if ( !defined($done->{$v}) ) {
377                 print("Lang var $v missing from $f\n");
378                 $errors++;
379             }
380         }
381     }
382     return $errors;
383 }