X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=bin%2FBackupPC;h=61276e22fdbf0ae89bde61b00350fb720aac21ca;hp=e6bc5f15fb45c14b5de8d07cb81da6ec24900a9e;hb=2c14784ad71874ec850d189060fe63d6eb9eba95;hpb=74dc9d456332757127d5eda4ce32f29377133fa2 diff --git a/bin/BackupPC b/bin/BackupPC index e6bc5f1..61276e2 100755 --- a/bin/BackupPC +++ b/bin/BackupPC @@ -1,4 +1,4 @@ -#!/bin/perl -T +#!/bin/perl #============================================================= -*-perl-*- # # BackupPC: Main program for PC backups. @@ -29,7 +29,7 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2001 Craig Barratt +# Copyright (C) 2001-2003 Craig Barratt # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -47,13 +47,14 @@ # #======================================================================== # -# Version 2.0.0beta3, released 1 Jun 2003. +# Version 2.1.0_CVS, released 8 Feb 2004. # # See http://backuppc.sourceforge.net. # #======================================================================== use strict; +no utf8; use vars qw(%Status %Info $Hosts); use lib "/usr/local/BackupPC/lib"; use BackupPC::Lib; @@ -299,6 +300,7 @@ sub Main_Initialize $Info{ConfigModTime} = $bpc->ConfigMTime(); $Info{pid} = $$; $Info{startTime} = time; + $Info{ConfigLTime} = time; $Info{Version} = $bpc->{Version}; # @@ -476,7 +478,7 @@ sub Main_TryToRun_Bg_or_User_Queue next; } push(@args, $req->{doFull} ? "-f" : "-i") - if ( !$req->{restore} ); + if (( !$req->{restore} ) && ( !$req->{archive} )); $UserQueueOn{$req->{host}} = 0; } elsif ( $nJobs < $Conf{MaxBackups} && (@CmdQueue + $nJobs) @@ -537,6 +539,10 @@ sub Main_TryToRun_Bg_or_User_Queue $progName = "BackupPC_restore"; $type = "restore"; push(@args, $req->{hostIP}, $req->{host}, $req->{reqFileName}); + } elsif ( $req->{archive} ) { + $progName = "BackupPC_archive"; + $type = "archive"; + push(@args, $req->{user}, $req->{host}, $req->{reqFileName}); } else { $progName = "BackupPC_dump"; $type = "backup"; @@ -596,13 +602,7 @@ sub Main_Select = localtime(time); my($currHours) = $hour + $min / 60 + $sec / 3600; if ( $bpc->ConfigMTime() != $Info{ConfigModTime} ) { - my($mesg) = $bpc->ConfigRead() - || "Re-read config file because mtime changed"; - print(LOG $bpc->timeStamp, "$mesg\n"); - %Conf = $bpc->Conf(); - $Info{ConfigModTime} = $bpc->ConfigMTime(); - umask($Conf{UmaskMode}); - ServerSocketInit(); + ServerReload("Re-read config file because mtime changed"); } my $delta = -1; foreach my $t ( @{$Conf{WakeupSchedule} || [0..23]} ) { @@ -650,30 +650,9 @@ sub Main_Process_Signal # Process signals # if ( $SigName eq "HUP" ) { - my($mesg) = $bpc->ConfigRead() - || "Re-read config file because of a SIG_HUP"; - print(LOG $bpc->timeStamp, "$mesg\n"); - $Info{ConfigModTime} = $bpc->ConfigMTime(); - %Conf = $bpc->Conf(); - umask($Conf{UmaskMode}); - ServerSocketInit(); - HostsUpdate(0); - $NextWakeup = 0; + ServerReload("Re-read config file because of a SIG_HUP"); } elsif ( $SigName ) { - print(LOG $bpc->timeStamp, "Got signal $SigName... cleaning up\n"); - if ( keys(%Jobs) ) { - foreach my $host ( keys(%Jobs) ) { - kill(2, $Jobs{$host}{pid}); - } - sleep(1); - foreach my $host ( keys(%Jobs) ) { - kill(9, $Jobs{$host}{pid}); - } - %Jobs = (); - } - StatusWrite(); - unlink("$TopDir/log/BackupPC.pid"); - exit(1); + ServerShutdown("Got signal $SigName... cleaning up"); } $SigName = ""; } @@ -839,6 +818,17 @@ sub Main_Check_Job_Messages $Status{$host}{startTime} = time; $Status{$host}{deadCnt} = 0; $Status{$host}{aliveCnt}++; + } elsif ( $mesg =~ /^started_archive/ ) { + $Jobs{$host}{type} = "archive"; + print(LOG $bpc->timeStamp, + "Started archive on $host" + . " (pid=$Jobs{$host}{pid})\n"); + $Status{$host}{state} = "Status_archive_in_progress"; + $Status{$host}{reason} = ""; + $Status{$host}{type} = "archive"; + $Status{$host}{startTime} = time; + $Status{$host}{deadCnt} = 0; + $Status{$host}{aliveCnt}++; } elsif ( $mesg =~ /^(full|incr) backup complete/ ) { print(LOG $bpc->timeStamp, "Finished $1 backup on $host\n"); $Status{$host}{reason} = "Reason_backup_done"; @@ -851,6 +841,12 @@ sub Main_Check_Job_Messages delete($Status{$host}{error}); delete($Status{$host}{errorTime}); $Status{$host}{endTime} = time; + } elsif ( $mesg =~ /^archive complete/ ) { + print(LOG $bpc->timeStamp, "Finished archive on $host\n"); + $Status{$host}{reason} = "Reason_archive_done"; + delete($Status{$host}{error}); + delete($Status{$host}{errorTime}); + $Status{$host}{endTime} = time; } elsif ( $mesg =~ /^nothing to do/ ) { if ( $Status{$host}{reason} ne "Reason_backup_failed" && $Status{$host}{reason} ne "Reason_restore_failed" ) { @@ -889,6 +885,13 @@ sub Main_Check_Job_Messages $Status{$host}{errorTime} = time; $Status{$host}{endTime} = time; print(LOG $bpc->timeStamp, "Restore failed on $host ($1)\n"); + } elsif ( $mesg =~ /^archive failed: (.*)/ ) { + $Status{$host}{state} = "Status_idle"; + $Status{$host}{reason} = "Reason_archive_failed"; + $Status{$host}{error} = $1; + $Status{$host}{errorTime} = time; + $Status{$host}{endTime} = time; + print(LOG $bpc->timeStamp, "Archive failed on $host ($1)\n"); } elsif ( $mesg =~ /^log\s+(.*)/ ) { print(LOG $bpc->timeStamp, "$1\n"); } elsif ( $mesg =~ /^BackupPC_stats = (.*)/ ) { @@ -1054,6 +1057,9 @@ sub Main_Check_Client_Messages if ( $Jobs{$host}{type} eq "restore" ) { $Status{$host}{reason} = "Reason_restore_canceled_by_user"; + } elsif ( $Jobs{$host}{type} eq "archive" ) { + $Status{$host}{reason} + = "Reason_archive_canceled_by_user"; } else { $Status{$host}{reason} = "Reason_backup_canceled_by_user"; @@ -1125,6 +1131,36 @@ sub Main_Check_Client_Messages $UserQueueOn{$hostIP} = 1; $reply = "ok: requested backup of $host"; } + } elsif ( $cmd =~ /^archive (\S+)\s+(\S+)\s+(\S+)/ ) { + my $user = $1; + my $archivehost = $2; + my $reqFileName = $3; + $host = $bpc->uriUnesc($archivehost); + if ( !defined($Status{$host}) ) { + print(LOG $bpc->timeStamp, + "User $user requested archive of unknown archive host" + . " $host"); + $reply = "archive error: unknown archive host $host"; + } else { + print(LOG $bpc->timeStamp, + "User $user requested archive on $host" + . " ($host)\n"); + if ( defined($Jobs{$host}) ) { + $reply = "Archive currently running on $host, please try later"; + } else { + unshift(@UserQueue, { + host => $host, + hostIP => $user, + reqFileName => $reqFileName, + reqTime => time, + dhcp => 0, + archive => 1, + userReq => 1, + }); + $UserQueueOn{$host} = 1; + $reply = "ok: requested archive on $host"; + } + } } elsif ( $cmd =~ /^restore (\S+)\s+(\S+)\s+(\S+)\s+(\S+)/ ) { my $hostIP = $1; $host = $2; @@ -1210,6 +1246,15 @@ sub Main_Check_Client_Messages QueueLink($host); } elsif ( $cmd =~ /^log\s+(.*)/ ) { print(LOG $bpc->timeStamp, "$1\n"); + } elsif ( $cmd =~ /^server\s+(\w+)/ ) { + my($type) = $1; + if ( $type eq 'reload' ) { + ServerReload("Reloading config/host files via CGI request"); + } elsif ( $type eq 'shutdown' ) { + $reply = "Shutting down...\n"; + syswrite($Clients{$client}{fh}, $reply, length($reply)); + ServerShutdown("Server shutting down..."); + } } elsif ( $cmd =~ /^quit/ || $cmd =~ /^exit/ ) { $nbytes = 0; last; @@ -1529,3 +1574,46 @@ sub ServerSocketInit $ServerInetPort = $Conf{ServerPort}; } } + +# +# Reload the server. Used by Main_Process_Signal when $SigName eq "HUP" +# or when the command "server reload" is received. +# +sub ServerReload +{ + my($mesg) = @_; + $mesg = $bpc->ConfigRead() || $mesg; + print(LOG $bpc->timeStamp, "$mesg\n"); + $Info{ConfigModTime} = $bpc->ConfigMTime(); + %Conf = $bpc->Conf(); + umask($Conf{UmaskMode}); + ServerSocketInit(); + HostsUpdate(0); + $NextWakeup = 0; + $Info{ConfigLTime} = time; +} + +# +# Gracefully shutdown the server. Used by Main_Process_Signal when +# $SigName ne "" && $SigName ne "HUP" or when the command +# "server shutdown" is received. +# +sub ServerShutdown +{ + my($mesg) = @_; + print(LOG $bpc->timeStamp, "$mesg\n"); + if ( keys(%Jobs) ) { + foreach my $host ( keys(%Jobs) ) { + kill(2, $Jobs{$host}{pid}); + } + sleep(1); + foreach my $host ( keys(%Jobs) ) { + kill(9, $Jobs{$host}{pid}); + } + %Jobs = (); + } + StatusWrite(); + unlink("$TopDir/log/BackupPC.pid"); + exit(1); +} +