From boxbackup-dev at boxbackup.org Sun Nov 2 00:03:50 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 2 Nov 2008 00:03:50 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2373 - box/trunk/distribution/boxbackup Message-ID: <20081102000350.9C721325012@www.boxbackup.org> Author: jamesog Date: 2008-11-02 00:03:49 +0000 (Sun, 02 Nov 2008) New Revision: 2373 Modified: box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt Log: Update distribution manifest to include the DocBook XML sources, as requested by Reinhard Tartler. Modified: box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt =================================================================== --- box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt 2008-10-29 20:58:32 UTC (rev 2372) +++ box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt 2008-11-02 00:03:49 UTC (rev 2373) @@ -28,6 +28,29 @@ docs/box-html/instguide docs/htmlguide/instguide docs/box-html/man-html docs/htmlguide/manpages docs/man +MKDIR docs/docbook +RUN cd docs; sed -i "" -e '/^ExceptionCodes/,/^$/s/\(.*\)/# &/' Makefile +docs/Makefile docs/docbook/Makefile +docs/ExceptionCodes.xml docs/docbook/ExceptionCodes.xml +docs/adminguide.xml docs/docbook/adminguide.xml +docs/bb-book.xsl docs/docbook/bb-book.xsl +docs/bb-man.xsl.tmpl docs/docbook/bb-man.xsl.tmpl +docs/bb-nochunk-book.xsl docs/docbook/bb-nochunk-book.xsl +docs/bbackupctl.xml docs/docbook/bbackupctl.xml +docs/bbackupd-config.xml docs/docbook/bbackupd-config.xml +docs/bbackupd.conf.xml docs/docbook/bbackupd.conf.xml +docs/bbackupd.xml docs/docbook/bbackupd.xml +docs/bbackupquery.xml docs/docbook/bbackupquery.xml +docs/bbstoreaccounts.xml docs/docbook/bbstoreaccounts.xml +docs/bbstored-certs.xml docs/docbook/bbstored-certs.xml +docs/bbstored-config.xml docs/docbook/bbstored-config.xml +docs/bbstored.conf.xml docs/docbook/bbstored.conf.xml +docs/bbstored.xml docs/docbook/bbstored.xml +docs/instguide.xml docs/docbook/instguide.xml +docs/raidfile-config.xml docs/docbook/raidfile-config.xml +docs/raidfile.conf.xml docs/docbook/raidfile.conf.xml +docs/html docs/docbook/html +docs/html/images docs/docbook/html/images TODO.txt BUGS.txt contrib From boxbackup-dev at boxbackup.org Sat Nov 8 13:19:49 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sat, 8 Nov 2008 13:19:49 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2374 - box/trunk/contrib Message-ID: <20081108131949.3FEA3325018@www.boxbackup.org> Author: chris Date: 2008-11-08 13:19:48 +0000 (Sat, 08 Nov 2008) New Revision: 2374 Added: box/trunk/contrib/bbadmin/ Log: Create directory for admin web interface. See WebManagementInterface. From boxbackup-dev at boxbackup.org Sat Nov 8 13:37:45 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sat, 8 Nov 2008 13:37:45 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2375 - box/trunk/contrib/bbadmin Message-ID: <20081108133745.B9348325018@www.boxbackup.org> Author: chris Date: 2008-11-08 13:37:45 +0000 (Sat, 08 Nov 2008) New Revision: 2375 Added: box/trunk/contrib/bbadmin/accounts.cgi box/trunk/contrib/bbadmin/apache.conf box/trunk/contrib/bbadmin/bb.css Log: Add the WebManagementInterface to contribs. Added: box/trunk/contrib/bbadmin/accounts.cgi =================================================================== --- box/trunk/contrib/bbadmin/accounts.cgi (rev 0) +++ box/trunk/contrib/bbadmin/accounts.cgi 2008-11-08 13:37:45 UTC (rev 2375) @@ -0,0 +1,579 @@ +#!/usr/bin/perl + +# Box Backup web management interface (c) Chris Wilson, 2008 +# +# LICENSE: The Box Backup license applies to this code, with the following +# additional conditions: +# +# If you make any changes to this code, except for changes to existing +# variables in the Configuration section below, you must publish the changes +# under the same license, whether or not you distribute copies of the +# changed version. +# +# If you use any of this code in a derivative work, you must publish the +# source code of the derivative work under the same or compatible license, +# whether or not you distribute copies of the derivative work. +# +# The terms of the Box Backup license may be viewed here: +# https://www.boxbackup.org/license.html +# +# If you require access to the code under a different license, this may +# be negotiated with the copyright holder. + +use strict; +use warnings; + +# Variables which you may need to change to match your installation +# Changes to existing variables are NOT required to be published. + +my $box_dir = "/etc/box"; +my $bbstored_dir = "$box_dir/bbstored"; +my $ca_dir = "/mnt/backup/boxbackup/ca"; + +# You should not need to change these unless you have a non-standard installation + +my $bbstored_conf_file = "$box_dir/bbstored.conf"; +my $bbstoreaccounts = "/usr/local/sbin/bbstoreaccounts"; +my $accounts_db_file = undef; +# my $accounts_db_file = "/etc/box/bbstored/accounts.txt"; +my $raidfile_conf_file = undef; +# my $raidfile_conf_file = "/etc/box/raidfile.conf"; +my $sign_period = '5000'; + +# install Perl module with: +# perl -MCPAN -e 'install Config::Scoped' +# perl -MCPAN -e 'force install P/PT/PTHOMSEN/BoxBackup/BBConfig-0.03.tar.gz' +# perl -MCPAN -e 'install Convert::ASN1' +# download http://search.cpan.org/CPAN/authors/id/L/LE/LEO/Convert-X509-0.1.tar.gz, +# unpack, and move the Convert folder to /usr/lib/perl5/site_perl/X.X.X + +# Check that SSL is being used. +# DO NOT DISABLE THIS unless you really know what you're doing! +die "This script requires an SSL web server" unless $ENV{HTTPS}; + +# Check that the script is protected by basic authentication. +# DO NOT DISABLE THIS unless you really know what you're doing! +die "This script requires HTTP Authentication" unless $ENV{REMOTE_USER}; + +# You should not need to change anything below this line. +# If you do, you must publish your changes to comply with the license. + +use BoxBackup::Config::Accounts; +use BoxBackup::Config::DiskSets; +use CGI::Carp qw(fatalsToBrowser); +use CGI::Pretty; +use Config::Scoped; +use Convert::X509::Request; +use English; +use Fcntl; +use File::Temp; +use URI; +use URI::QueryParam; + +sub check_access($$) +{ + my ($file,$desc) = @_; + unless (-r $file) + { + open FILE, "< $file" and die "should have failed"; + die "Failed to access $desc ($file): $!"; + } +} + +sub check_executable($$) +{ + my ($file,$desc) = @_; + unless (-x $file) + { + open FILE, "< $file" and die "should have failed"; + die "$desc is not executable ($file): $!"; + } +} + + +my $cgi = new CGI; + +if (my $download = $cgi->param("download")) +{ + my ($filename, $acct_no); + + if ($download eq "cert") + { + $acct_no = $cgi->param("account"); + $acct_no =~ tr/0-9a-fA-F//cd; + $filename = "$acct_no-cert.pem"; + } + elsif ($download eq "cacert") + { + $filename = "serverCA.pem"; + } + else + { + die "No such download method $download"; + } + + print $cgi->header(-type => "text/plain", + -"content-disposition" => "attachment; filename=$filename"); + + my $send_file; + + if ($download eq "cert") + { + $send_file = "$ca_dir/clients/$filename"; + } + elsif ($download eq "cacert") + { + $send_file = "$ca_dir/roots/serverCA.pem"; + } + + die "File does not exist: $send_file" + unless -f $send_file; + die "File is not readable by user " . getpwuid($UID) . + ": $send_file" unless -r $send_file; + + open SENDFILE, "< $send_file" or die "Failed to open file " . + "$send_file: $!"; + while (my $line = ) + { + print $line; + } + close SENDFILE; + exit 0; +} + +print $cgi->header(), $cgi->start_html(-title=>"Box Backup Certificates", + -style=>'bb.css'); +print $cgi->h1("Box Backup Certificates"); + +check_access($bbstored_conf_file, "BBStoreD configuration file"); + +my $bbstored_conf = Config::Scoped->new(file => $bbstored_conf_file)->parse(); + +$accounts_db_file ||= $bbstored_conf->{'Server'}{'AccountDatabase'}; +die "Missing AccountDatabase in $bbstored_conf_file" unless $accounts_db_file; +check_access($accounts_db_file, "Accounts Database"); + +$raidfile_conf_file ||= $bbstored_conf->{'Server'}{'RaidFileConf'}; +die "Missing RaidFileConf in $bbstored_conf_file" unless $raidfile_conf_file; +check_access($raidfile_conf_file, "RaidFile configuration file"); + +my $accounts_db = BoxBackup::Config::Accounts->new($accounts_db_file); + +check_executable($bbstoreaccounts, "bbstoreaccounts program"); + +sub error($) +{ + my ($message) = @_; + unless ($message =~ /^p($message); + } + print $cgi->div({-class=>"error"}, $message); + return 0; +} + +sub url +{ + my $cgi = shift @_; + my %params = @_; + my $uri = URI->new($cgi->url(-absolute=>1)); + foreach my $param (keys %params) + { + $uri->query_param($param, $params{$param}); + } + return $uri; +} + +sub create_account($) +{ + my ($cgi) = @_; + + my $upload = $cgi->upload('req'); + unless ($upload) + { + return error("Please attach a certificate request file."); + } + + my $tempfile = File::Temp->new("bbaccount-certreq-XXXXXX.pem"); + my $csr_data = ""; + + while (my $line = <$upload>) + { + print $tempfile $line; + $csr_data .= $line; + } + + my @accounts = $accounts_db->getAccountIDs(); + my $new_acc_no = $cgi->param('account'); + if (not $new_acc_no) + { + return error("Please enter an account number."); + } + + foreach my $account_no (@accounts) + { + if ($account_no == $new_acc_no) + { + return error("The account number $new_acc_no " . + "already exists, please use one which " . + "does not."); + } + } + + my $req = Convert::X509::Request->new($csr_data); + my $cn; + foreach my $part ($req->subject) + { + if ($part =~ /^cn=(.*)/i) + { + $cn = $1; + last; + } + } + + unless ($cn) + { + return error("The certificate request does not include a " . + "common name, which should be BACKUP-$new_acc_no."); + } + + unless ($cn eq "BACKUP-$new_acc_no") + { + return error("The certificate request includes the wrong " . + "common name. Expected " . + "BACKUP-$new_acc_no but found " . + "$cn."); + } + + my $out_cert_dir = "$ca_dir/clients"; + unless (-w $out_cert_dir) + { + return error("Cannot write to certificate directory " . + "$out_cert_dir as user " . + "" . getpwuid($UID) . "."); + } + + my $out_cert = "$out_cert_dir/$new_acc_no-cert.pem"; + if (-f $out_cert and not -w $out_cert) + { + return error("The certificate file $out_cert " . + "exists and is not writable as user " . + "$out_cert_dir as user " . + "" . getpwuid($UID) . "."); + } + + my $client_ca_cert_file = "$ca_dir/roots/clientCA.pem"; + unless (-r $client_ca_cert_file) + { + return error("The client CA certificate file " . + "$client_ca_cert_file " . + "is not readable by user " . + "" . getpwuid($UID) . "."); + } + + my $client_ca_key_file = "$ca_dir/keys/clientRootKey.pem"; + unless (-r $client_ca_key_file) + { + return error("The client CA key file " . + "$client_ca_key_file " . + "is not readable by user " . + "" . getpwuid($UID) . "."); + } + + my $serial_file = "$ca_dir/roots/clientCA.srl"; + unless (-w $serial_file) + { + return error("The certificate serial number file " . + "$serial_file " . + "is not writable by user " . + "" . getpwuid($UID) . "."); + } + + my $outputfile = File::Temp->new("bbaccounts-openssl-output-XXXXXX"); + + if (system("openssl x509 -req -in $tempfile -sha1 " . + "-extensions usr_crt " . + "-CA $client_ca_cert_file " . + "-CAkey $client_ca_key_file " . + "-out $out_cert -days $sign_period " . + ">$outputfile 2>&1") != 0) + { + open ERR, "< $outputfile" or die "$outputfile: $!"; + my $errors = join("", ); + close ERR; + return error($cgi->p("Failed to sign certificate:") . + $cgi->pre($errors)); + } + + my $cert_uri = url($cgi, download => "cert", account => $new_acc_no); + my $ca_uri = url($cgi, download => "cacert"); + + print $cgi->div({-class=>"success"}, + $cgi->p("Account created. Please download the following " . + "files:") . + $cgi->ul( + $cgi->li($cgi->a({href=>$cert_uri}, + "Client Certificate")), + $cgi->li($cgi->a({href=>$ca_uri}, + "CA Certificate")) + ) + ); + + return 1; +} + +if ($cgi->param("create")) +{ + print $cgi->h2("Account Creation"); + create_account($cgi); +} + +print $cgi->h2("Accounts"); +print $cgi->start_table({-border=>0, -class=>"numbers"}); + +print $cgi->Tr( + $cgi->th("Account"), + $cgi->th('Used'), $cgi->th('%'), + $cgi->th('Old files'), $cgi->th('%'), + $cgi->th('Deleted files'), $cgi->th('%'), + $cgi->th('Directories'), $cgi->th('%'), + $cgi->th('Soft limit'), $cgi->th('%'), + $cgi->th('Hard limit'), + $cgi->th('Actions') + ); + +sub human_format($) +{ + my ($kb) = @_; + die unless $kb =~ /^(\d+) (kB)$/; + + my $value = $1; + my $units = $2; + + if ($value > 1024) + { + $value /= 1024; + $units = "MB"; + } + + if ($value > 1024) + { + $value /= 1024; + $units = "GB"; + } + + $value = sprintf("%.1f", $value); + return "$value $units"; +} + +sub bbstoreaccounts_format($) +{ + my ($kb) = @_; + die unless $kb =~ /^(\d+) (kB)$/; + + my $value = $1; + my $units = "K"; + + unless ($value % 1024) + { + $value /= 1024; + $units = "M"; + } + + unless ($value % 1024) + { + $value /= 1024; + $units = "G"; + } + + return "$value$units"; +} + +sub get_account_info($) +{ + my ($account) = @_; + + open BBSA, "$bbstoreaccounts -c $bbstored_conf_file -m info $account |" + or die "Failed to get account info for $account: $!"; + + my $account_info = {}; + + while (my $line = ) + { + unless ($line =~ m/([^:]*): (.*)/) + { + die "Bad format in bbstoreaccounts info output " . + "for account $account: '$line'"; + } + + my $name = $1; + my $value = $2; + + if ($value =~ /(.*), (.*)/) + { + $account_info->{$name} = [$1, $2]; + } + else + { + $account_info->{$name} = $value; + } + } + + return $account_info; +} + +sub format_account_info($) +{ + my ($values) = @_; + my $kb = $values->[0]; + my $pc = $values->[1]; + return $cgi->td(human_format($kb)), $cgi->td($values->[1]); +} + +my %account_numbers; + +my @accounts = $accounts_db->getAccountIDs(); +foreach my $i (@accounts) +{ + die "Duplicate account number $i" if $account_numbers{hex($i)}; + $account_numbers{hex($i)} = 1; + + # Find out what account is on what diskset. + my $disk = $accounts_db->getDisk($i); + + # store limits + my $account_info = get_account_info($i); + + print $cgi->Tr( + $cgi->td($i), + format_account_info($account_info->{'Used'}), + format_account_info($account_info->{'Old files'}), + format_account_info($account_info->{'Deleted files'}), + format_account_info($account_info->{'Directories'}), + format_account_info($account_info->{'Soft limit'}), + $cgi->td(human_format($account_info->{'Hard limit'}[0])), + $cgi->td($cgi->a({-href=>url($cgi, account=>$i)}, + "Edit")) + ); +} + +print $cgi->end_table(); + +my $account_no = $cgi->param("account"); +$account_no =~ tr/0-9a-fA-F//cd; + +if (not $cgi->param("showcreate")) +{ + print $cgi->start_form, + $cgi->submit(-name=>"showcreate", + -value=>"Create Account"), + $cgi->end_form(); +} + +if ($account_no) +{ + print $cgi->h2("Edit Account"); + my $account_info = get_account_info($account_no); + $cgi->param("account", $account_no); + $cgi->param("soft_limit", + bbstoreaccounts_format($account_info->{'Soft limit'}[0])); + $cgi->param("hard_limit", + bbstoreaccounts_format($account_info->{'Hard limit'}[0])); +} +elsif ($cgi->param("showcreate")) +{ + print $cgi->h2("Create Account"); +} + +if ($account_no or $cgi->param("showcreate")) +{ + my $new_account_no = 1; + while ($account_numbers{$new_account_no}) + { + $new_account_no++; + } + + my $disksets_conf = BoxBackup::Config::DiskSets->new($raidfile_conf_file); + my @disk_names = $disksets_conf->getListofDisks(); + my @disk_numbers; + my %disk_labels; + + foreach my $name (@disk_names) + { + my $num = $disksets_conf->getParamVal($name, "SetNumber"); + push @disk_numbers, $num; + $disk_labels{$num} = $name; + } + + print $cgi->start_multipart_form(), + $cgi->start_table(); + + if ($account_no) + { + print $cgi->Tr( + $cgi->th("Account Number"), + $cgi->td($account_no . + $cgi->hidden("account", $account_no)) + ); + } + else + { + print $cgi->Tr( + $cgi->th("Account Number"), + $account_no ? $account_no : + $cgi->td($cgi->textfield(-name => "account", + -default => sprintf("%x", $new_account_no))), + ); + } + + if (not $account_no) + { + print $cgi->Tr( + $cgi->th("Disk Set"), + $cgi->td($cgi->popup_menu(-name => "disk_set", + -values => \@disk_numbers, + -labels => \%disk_labels)) + ); + } + + print $cgi->Tr( + $cgi->th("Soft Limit"), + $cgi->td($cgi->textfield(-name => "soft_limit", + -default => "10G")) + ), + $cgi->Tr( + $cgi->th("Hard Limit"), + $cgi->td($cgi->textfield(-name => "hard_limit", + -default => "20G")) + ), + $cgi->Tr( + $cgi->th("Certificate Request"), + $cgi->td($cgi->filefield({ + -name => "req", + -default => "*.crt" + })) + ); + + if ($account_no) + { + print $cgi->Tr( + $cgi->th(), + $cgi->td($cgi->submit(-name => "update", + -value => "Update Account")) + ); + } + else + { + print $cgi->Tr( + $cgi->th(), + $cgi->td($cgi->submit(-name => "create", + -value => "Create Account")) + ); + } + + print $cgi->end_table(), $cgi->end_form(); +} + +print $cgi->end_html; + +exit 0; Property changes on: box/trunk/contrib/bbadmin/accounts.cgi ___________________________________________________________________ Added: svn:executable + * Added: box/trunk/contrib/bbadmin/apache.conf =================================================================== --- box/trunk/contrib/bbadmin/apache.conf (rev 0) +++ box/trunk/contrib/bbadmin/apache.conf 2008-11-08 13:37:45 UTC (rev 2375) @@ -0,0 +1,14 @@ +Alias /bbadmin /var/www/localhost/bbadmin + + + AuthType basic + AuthName "Box Backup Web Management Interface" + AuthUserFile /etc/apache2/bbadmin.cgi.htpasswd + Require valid-user + + Allow from all + + Options ExecCGI + AddHandler cgi-script .cgi + DirectoryIndex accounts.cgi + Added: box/trunk/contrib/bbadmin/bb.css =================================================================== --- box/trunk/contrib/bbadmin/bb.css (rev 0) +++ box/trunk/contrib/bbadmin/bb.css 2008-11-08 13:37:45 UTC (rev 2375) @@ -0,0 +1,70 @@ +body +{ + background: #edeef3; +} + +table +{ + border-spacing: 0px; +} + +h1, th +{ + background: #e4e6ed; +} + +h1 +{ + border-top: 1px solid #c4c4d5; + border-bottom: 1px solid #fff; +} + +td, th +{ + border-top: 1px solid #fff; + border-bottom: 1px solid #c4c4d5; + margin: 0px; + padding: 0.2em 0.5em; +} + +th +{ + text-align: left; +} + +table.numbers td +{ + text-align: right; +} + +div.error, div.success +{ + margin: 1em; +} + +div.error>*, div.success>* +{ + margin: 0.5em; +} + +div.error +{ + background: #fdd; + border: 2px solid #c00; +} + +div.success +{ + background: #dfd; + border: 2px solid #0c0; +} + +h2, table, p +{ + margin: 0.5em; +} + +form +{ + margin: 0.5em 0; +} From boxbackup-dev at boxbackup.org Sat Nov 8 22:16:06 2008 From: boxbackup-dev at boxbackup.org (Box Backup) Date: Sat, 08 Nov 2008 22:16:06 -0000 Subject: [Box Backup-commit] #48: Locations that don't exist on first run are never tried again Message-ID: <042.d771657005e39c6fa5fef53f64e95455@boxbackup.org> #48: Locations that don't exist on first run are never tried again ------------------------------------------------------------------------+--- Reporter: chris | Owner: chris Type: defect | Status: new Priority: normal | Milestone: 0.12 Component: bbackupd | Version: 0.11rc1 Keywords: backup location not available retry backup-ok notification | ------------------------------------------------------------------------+--- Torsten reports: ''if i have a location not existing locally and not existing on the store but activated as a location in bbackupd.conf. With this configuration box backup throws this errors on start.'' {{{ ERROR: Failed to stat file: '/test-192.168.1.87-torsten': No such file or directory (2) WARNING: Exception thrown: CommonException(OSFileError) at BackupClientFileAttributes.cpp(309) ERROR: Failed to get attributes for path '/test-192.168.1.87-torsten', skipping location 'test-192.168.1.87-torsten' WARNING: Failed to access directory: /test-192.168.1.87-torsten: No such file or directory NOTICE: About to notify administrator about event backup-ok, running script '/root/exobackup/boxbackup/NotifySysadmin.sh backup-ok' }}} * ''this errors are only printed once. The next backup runs do not consider to backup this location. That is not good for me. I have locations on remote storage mounted via samba. So only one mount error and i will never again be notified that this location is not backed up.'' * ''is this the right behavior, that backup-ok is called even though there was this error?'' ''I attached a little patch that makes box backup to retry this location. But i dont think that this is a clean way.'' -- Ticket URL: Box Backup An open source, completely automatic on-line backup system for UNIX. From boxbackup-dev at boxbackup.org Sat Nov 8 22:18:55 2008 From: boxbackup-dev at boxbackup.org (Box Backup) Date: Sat, 08 Nov 2008 22:18:55 -0000 Subject: [Box Backup-commit] Re: #48: Locations that don't exist on first run are never tried again In-Reply-To: <042.d771657005e39c6fa5fef53f64e95455@boxbackup.org> References: <042.d771657005e39c6fa5fef53f64e95455@boxbackup.org> Message-ID: <051.985c069a9cf4e5f217cac71ea37ec07f@boxbackup.org> #48: Locations that don't exist on first run are never tried again -----------------------+---------------------------------------------------- Reporter: chris | Owner: chris Type: defect | Status: new Priority: normal | Milestone: 0.12 Component: bbackupd | Version: 0.11rc1 Resolution: | Keywords: backup location not available retry backup-ok notification -----------------------+---------------------------------------------------- Old description: > Torsten reports: > > ''if i have a location not existing locally and not existing on the store > but > activated as a location in bbackupd.conf. With this configuration box > backup > throws this errors on start.'' > > {{{ > ERROR: Failed to stat file: '/test-192.168.1.87-torsten': No such file or > directory (2) > WARNING: Exception thrown: CommonException(OSFileError) at > BackupClientFileAttributes.cpp(309) > ERROR: Failed to get attributes for path '/test-192.168.1.87-torsten', > skipping location 'test-192.168.1.87-torsten' > WARNING: Failed to access directory: /test-192.168.1.87-torsten: No such > file or directory > NOTICE: About to notify administrator about event backup-ok, running > script '/root/exobackup/boxbackup/NotifySysadmin.sh backup-ok' > }}} > > * ''this errors are only printed once. The next backup runs do not > consider to > backup this location. That is not good for me. I have locations on remote > storage mounted via samba. So only one mount error and i will never again > be > notified that this location is not backed up.'' > > * ''is this the right behavior, that backup-ok is called even though > there was > this error?'' > > ''I attached a little patch that makes box backup to retry this location. > But i > dont think that this is a clean way.'' New description: Torsten reports: If i have a location not existing locally and not existing on the store but activated as a location in bbackupd.conf. With this configuration box backup throws this errors on start. {{{ ERROR: Failed to stat file: '/test-192.168.1.87-torsten': No such file or directory (2) WARNING: Exception thrown: CommonException(OSFileError) at BackupClientFileAttributes.cpp(309) ERROR: Failed to get attributes for path '/test-192.168.1.87-torsten', skipping location 'test-192.168.1.87-torsten' WARNING: Failed to access directory: /test-192.168.1.87-torsten: No such file or directory NOTICE: About to notify administrator about event backup-ok, running script '/root/exobackup/boxbackup/NotifySysadmin.sh backup-ok' }}} * this errors are only printed once. The next backup runs do not consider to backup this location. That is not good for me. I have locations on remote storage mounted via samba. So only one mount error and i will never again be notified that this location is not backed up. * is this the right behavior, that backup-ok is called even though there was this error? I attached a little patch that makes box backup to retry this location. But i dont think that this is a clean way. -- Ticket URL: Box Backup An open source, completely automatic on-line backup system for UNIX. From boxbackup-dev at boxbackup.org Tue Nov 11 00:26:11 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Tue, 11 Nov 2008 00:26:11 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2376 - box/trunk/contrib/bbadmin Message-ID: <20081111002611.DB589325018@www.boxbackup.org> Author: chris Date: 2008-11-11 00:26:11 +0000 (Tue, 11 Nov 2008) New Revision: 2376 Modified: box/trunk/contrib/bbadmin/accounts.cgi Log: Additional debugging for value format error reported by Scott McNee. Modified: box/trunk/contrib/bbadmin/accounts.cgi =================================================================== --- box/trunk/contrib/bbadmin/accounts.cgi 2008-11-08 13:37:45 UTC (rev 2375) +++ box/trunk/contrib/bbadmin/accounts.cgi 2008-11-11 00:26:11 UTC (rev 2376) @@ -345,7 +345,8 @@ sub human_format($) { my ($kb) = @_; - die unless $kb =~ /^(\d+) (kB)$/; + die "bad format in value: expected number followed by kB, " . + "found '$kb'" unless $kb =~ /^(\d+) (kB)$/; my $value = $1; my $units = $2; From boxbackup-dev at boxbackup.org Tue Nov 11 00:43:48 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Tue, 11 Nov 2008 00:43:48 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2377 - box/trunk/bin/bbackupd/win32 Message-ID: <20081111004348.D1115325018@www.boxbackup.org> Author: chris Date: 2008-11-11 00:43:48 +0000 (Tue, 11 Nov 2008) New Revision: 2377 Modified: box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs Log: Fix NotifyScript syntax error reported by Roy. Ignore "backup-ok" messages in NotifyScript by default. Modified: box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs =================================================================== --- box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs 2008-11-11 00:26:11 UTC (rev 2376) +++ box/trunk/bin/bbackupd/win32/NotifySysAdmin.vbs 2008-11-11 00:43:48 UTC (rev 2377) @@ -32,7 +32,7 @@ ElseIf args(0) = "read-error" Then subject = subjtmpl & " (read errors)" body = "Errors occurred reading some files or directories " & _ - "for backup on " & hostname & "." _ & vbCrLf & _ + "for backup on " & hostname & "." & vbCrLf & _ vbCrLf & _ "===================================" & vbCrLf & _ "THESE FILES ARE NOT BEING BACKED UP" & vbCrLf & _ @@ -55,7 +55,8 @@ "information about the error, " & vbCrLf & _ "and take appropriate action." & vbCrLf SendMail from,sendto,subject,body -ElseIf args(0) = "backup-start" Or args(0) = "backup-finish" Then +ElseIf args(0) = "backup-start" Or args(0) = "backup-finish" _ + Or args(0) = "backup-ok" Then ' do nothing for these messages by default Else subject = subjtmpl & " (unknown)" From boxbackup-dev at boxbackup.org Wed Nov 12 01:10:35 2008 From: boxbackup-dev at boxbackup.org (Box Backup) Date: Wed, 12 Nov 2008 01:10:35 -0000 Subject: [Box Backup-commit] #49: ID map (rename tracking) broken since [288] Message-ID: <042.11cf44ddc3b5bb942976c0e8d0ec1c48@boxbackup.org> #49: ID map (rename tracking) broken since [288] ----------------------+----------------------------------------------------- Reporter: chris | Owner: chris Type: defect | Status: new Priority: normal | Milestone: 0.12 Component: bbackupd | Version: 0.11rc1 Keywords: | ----------------------+----------------------------------------------------- bin/bbackupd/BackupClientInodeToIDMap.h checks for HAVE_DB which is not defined anywhere any more, since [288] removed the call to AX_CHECK_BDB_V1. -- Ticket URL: Box Backup An open source, completely automatic on-line backup system for UNIX. From boxbackup-dev at boxbackup.org Sat Nov 15 22:14:05 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sat, 15 Nov 2008 22:14:05 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2378 - box/trunk/lib/raidfile Message-ID: <20081115221405.7A9EE325021@www.boxbackup.org> Author: chris Date: 2008-11-15 22:14:04 +0000 (Sat, 15 Nov 2008) New Revision: 2378 Modified: box/trunk/lib/raidfile/RaidFileUtil.cpp Log: Fix typo in variable name. Modified: box/trunk/lib/raidfile/RaidFileUtil.cpp =================================================================== --- box/trunk/lib/raidfile/RaidFileUtil.cpp 2008-11-11 00:43:48 UTC (rev 2377) +++ box/trunk/lib/raidfile/RaidFileUtil.cpp 2008-11-15 22:14:04 UTC (rev 2378) @@ -30,11 +30,13 @@ // Created: 2003/07/11 // // -------------------------------------------------------------------------- -RaidFileUtil::ExistType RaidFileUtil::RaidFileExists(RaidFileDiscSet &rDiscSet, const std::string &rFilename, int *pStartDisc, int *pExisitingFiles, int64_t *pRevisionID) +RaidFileUtil::ExistType RaidFileUtil::RaidFileExists(RaidFileDiscSet &rDiscSet, + const std::string &rFilename, int *pStartDisc, int *pExistingFiles, + int64_t *pRevisionID) { - if(pExisitingFiles) + if(pExistingFiles) { - *pExisitingFiles = 0; + *pExistingFiles = 0; } // For stat call, although the results are not examined @@ -89,9 +91,9 @@ // Component file exists, add to count rfCount++; // Set flags for existance? - if(pExisitingFiles) + if(pExistingFiles) { - (*pExisitingFiles) |= (1 << f); + (*pExistingFiles) |= (1 << f); } // Revision ID if(pRevisionID != 0) From boxbackup-dev at boxbackup.org Sat Nov 22 14:33:25 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sat, 22 Nov 2008 14:33:25 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2379 - in box/trunk: . contrib/mac_osx Message-ID: <20081122143325.D7551325021@www.boxbackup.org> Author: jamesog Date: 2008-11-22 14:33:25 +0000 (Sat, 22 Nov 2008) New Revision: 2379 Added: box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist.in box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist.in Removed: box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist Modified: box/trunk/configure.ac Log: Autoconfify the OS X plist files Modified: box/trunk/configure.ac =================================================================== --- box/trunk/configure.ac 2008-11-15 22:14:04 UTC (rev 2378) +++ box/trunk/configure.ac 2008-11-22 14:33:25 UTC (rev 2379) @@ -335,6 +335,8 @@ bin/bbstored/bbstored-config contrib/debian/bbackupd contrib/debian/bbstored + contrib/mac_osx/org.boxbackup.bbackupd.plist + contrib/mac_osx/org.boxbackup.bbstored.plist contrib/redhat/bbackupd contrib/redhat/bbstored contrib/suse/bbackupd Deleted: box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist =================================================================== --- box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist 2008-11-15 22:14:04 UTC (rev 2378) +++ box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist 2008-11-22 14:33:25 UTC (rev 2379) @@ -1,14 +0,0 @@ - - - - - Label - org.boxbackup.bbackupd - RunAtLoad - - ProgramArguments - - /usr/local/bin/bbackupd - - - Copied: box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist.in (from rev 2378, box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist) =================================================================== --- box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist.in (rev 0) +++ box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist.in 2008-11-22 14:33:25 UTC (rev 2379) @@ -0,0 +1,14 @@ + + + + + Label + org.boxbackup.bbackupd + RunAtLoad + + ProgramArguments + + @prefix@/sbin/bbackupd + + + Property changes on: box/trunk/contrib/mac_osx/org.boxbackup.bbackupd.plist.in ___________________________________________________________________ Added: svn:mergeinfo + Deleted: box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist =================================================================== --- box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist 2008-11-15 22:14:04 UTC (rev 2378) +++ box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist 2008-11-22 14:33:25 UTC (rev 2379) @@ -1,14 +0,0 @@ - - - - - Label - org.boxbackup.bbstored - RunAtLoad - - ProgramArguments - - /usr/local/bin/bbstored - - - Copied: box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist.in (from rev 2378, box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist) =================================================================== --- box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist.in (rev 0) +++ box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist.in 2008-11-22 14:33:25 UTC (rev 2379) @@ -0,0 +1,14 @@ + + + + + Label + org.boxbackup.bbstored + RunAtLoad + + ProgramArguments + + @prefix@/sbin/bbstored + + + Property changes on: box/trunk/contrib/mac_osx/org.boxbackup.bbstored.plist.in ___________________________________________________________________ Added: svn:mergeinfo + From boxbackup-dev at boxbackup.org Sat Nov 22 15:28:12 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sat, 22 Nov 2008 15:28:12 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2380 - box/trunk/infrastructure Message-ID: <20081122152812.1E45A325021@www.boxbackup.org> Author: jamesog Date: 2008-11-22 15:28:11 +0000 (Sat, 22 Nov 2008) New Revision: 2380 Modified: box/trunk/infrastructure/makeparcels.pl.in Log: Allow use of literal paths in parcels.txt (i.e. files to be installed outside of $prefix) Modified: box/trunk/infrastructure/makeparcels.pl.in =================================================================== --- box/trunk/infrastructure/makeparcels.pl.in 2008-11-22 14:33:25 UTC (rev 2379) +++ box/trunk/infrastructure/makeparcels.pl.in 2008-11-22 15:28:11 UTC (rev 2380) @@ -237,7 +237,15 @@ my $local_install_dir = $install_into_dir; if (defined $dest) { - $local_install_dir = "@prefix@/$dest"; + if ($dest =~ m,^/,) + { + # Don't add $prefix if $dest is a literal path + $local_install_dir = $dest; + } + else + { + $local_install_dir = "@prefix@/$dest"; + } } print SCRIPT "mkdir -p " . "\${DESTDIR}$local_install_dir/\n"; From boxbackup-dev at boxbackup.org Sat Nov 22 15:28:35 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sat, 22 Nov 2008 15:28:35 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2381 - box/trunk Message-ID: <20081122152835.A3B43325021@www.boxbackup.org> Author: jamesog Date: 2008-11-22 15:28:35 +0000 (Sat, 22 Nov 2008) New Revision: 2381 Modified: box/trunk/parcels.txt Log: Install plist files for OS X Modified: box/trunk/parcels.txt =================================================================== --- box/trunk/parcels.txt 2008-11-22 15:28:11 UTC (rev 2380) +++ box/trunk/parcels.txt 2008-11-22 15:28:35 UTC (rev 2381) @@ -26,6 +26,10 @@ script contrib/solaris/bbackupd-smf-method lib/svc/method END-ONLY +ONLY:Darwin + script contrib/mac_osx/org.boxbackup.bbackupd.plist /Library/LaunchDaemons +END-ONLY + backup-server bin bbstored bin bbstoreaccounts @@ -38,3 +42,7 @@ script contrib/solaris/bbstored-manifest.xml lib/svc/manifest script contrib/solaris/bbstored-smf-method lib/svc/method END-ONLY + +ONLY:Darwin + script contrib/mac_osx/org.boxbackup.bbstored.plist /Library/LaunchDaemons +END-ONLY From boxbackup-dev at boxbackup.org Sun Nov 23 00:18:14 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 23 Nov 2008 00:18:14 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2382 - in box/trunk: . distribution/boxbackup Message-ID: <20081123001814.69F6A325018@www.boxbackup.org> Author: jamesog Date: 2008-11-23 00:18:13 +0000 (Sun, 23 Nov 2008) New Revision: 2382 Modified: box/trunk/configure.ac box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt Log: * Add OS X plists to the distribution * Revert the docs Makefile after distribution generation (certain parts are commented out for the distribution) * Reorder generated files in configure.ac so that files are not unnecessarily created executable Modified: box/trunk/configure.ac =================================================================== --- box/trunk/configure.ac 2008-11-22 15:28:35 UTC (rev 2381) +++ box/trunk/configure.ac 2008-11-23 00:18:13 UTC (rev 2382) @@ -328,37 +328,38 @@ AC_SUBST([box_version]) ### Output files -AC_CONFIG_FILES([infrastructure/BoxPlatform.pm]) +AC_CONFIG_FILES([infrastructure/BoxPlatform.pm + contrib/mac_osx/org.boxbackup.bbackupd.plist + contrib/mac_osx/org.boxbackup.bbstored.plist + contrib/solaris/bbackupd-manifest.xml + contrib/solaris/bbstored-manifest.xml + lib/common/BoxPortsAndFiles.h + test/bbackupd/testfiles/bbackupd.conf + test/bbackupd/testfiles/bbackupd-exclude.conf + test/bbackupd/testfiles/bbackupd-snapshot.conf + test/bbackupd/testfiles/bbackupd-symlink.conf + ]) AX_CONFIG_SCRIPTS([bin/bbackupd/bbackupd-config bin/bbackupquery/makedocumentation.pl bin/bbstored/bbstored-certs bin/bbstored/bbstored-config contrib/debian/bbackupd contrib/debian/bbstored - contrib/mac_osx/org.boxbackup.bbackupd.plist - contrib/mac_osx/org.boxbackup.bbstored.plist contrib/redhat/bbackupd contrib/redhat/bbstored contrib/suse/bbackupd contrib/suse/bbstored - contrib/solaris/bbackupd-manifest.xml - contrib/solaris/bbstored-manifest.xml contrib/solaris/bbackupd-smf-method contrib/solaris/bbstored-smf-method contrib/windows/installer/boxbackup.mpi infrastructure/makebuildenv.pl infrastructure/makeparcels.pl infrastructure/makedistribution.pl - lib/common/BoxPortsAndFiles.h lib/common/makeexception.pl lib/raidfile/raidfile-config lib/server/makeprotocol.pl runtest.pl test/backupstorefix/testfiles/testbackupstorefix.pl - test/bbackupd/testfiles/bbackupd.conf - test/bbackupd/testfiles/bbackupd-exclude.conf - test/bbackupd/testfiles/bbackupd-snapshot.conf - test/bbackupd/testfiles/bbackupd-symlink.conf test/bbackupd/testfiles/extcheck1.pl test/bbackupd/testfiles/extcheck2.pl test/bbackupd/testfiles/notifyscript.pl Modified: box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt =================================================================== --- box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt 2008-11-22 15:28:35 UTC (rev 2381) +++ box/trunk/distribution/boxbackup/DISTRIBUTION-MANIFEST.txt 2008-11-23 00:18:13 UTC (rev 2382) @@ -51,10 +51,12 @@ docs/raidfile.conf.xml docs/docbook/raidfile.conf.xml docs/html docs/docbook/html docs/html/images docs/docbook/html/images +RUN svn revert docs/Makefile TODO.txt BUGS.txt contrib NO-LICENSE-IN-DIR contrib/debian +NO-LICENSE-IN-DIR contrib/mac_osx NO-LICENSE-IN-DIR contrib/redhat NO-LICENSE-IN-DIR contrib/rpm REPLACE-VERSION-IN contrib/rpm/boxbackup.spec From boxbackup-dev at boxbackup.org Sun Nov 23 00:37:22 2008 From: boxbackup-dev at boxbackup.org (Box Backup) Date: Sun, 23 Nov 2008 00:37:22 -0000 Subject: [Box Backup-commit] #50: No way to capture stderr under Windows Message-ID: <042.be677009d42b205bdaca051d6918e9c2@boxbackup.org> #50: No way to capture stderr under Windows ----------------------------------------------------------------------------+ Reporter: chris | Owner: chris Type: defect | Status: new Priority: major | Milestone: 0.11 Component: bbackupquery | Version: 0.11rc1 Keywords: win32 error logging bbackupquery compare logging stderr errors | ----------------------------------------------------------------------------+ Errors and warnings are sent to stderr by the logging framework. This includes compare errors during `bbackupquery compare`. However there is no way to redirect stderr under Windows, and hence no way to capture these to a file. `bbackupquery` should support logging to a file with a command- line switch. -- Ticket URL: Box Backup An open source, completely automatic on-line backup system for UNIX. From boxbackup-dev at boxbackup.org Sun Nov 23 00:39:11 2008 From: boxbackup-dev at boxbackup.org (Box Backup) Date: Sun, 23 Nov 2008 00:39:11 -0000 Subject: [Box Backup-commit] #51: No way to force bbackupd to re-upload files under Windows Message-ID: <042.7f3457291cfd5ed9deb623505ef78e72@boxbackup.org> #51: No way to force bbackupd to re-upload files under Windows -----------------------------------------------------------+---------------- Reporter: chris | Owner: chris Type: defect | Status: new Priority: normal | Milestone: 0.11 Component: bbackupd | Version: 0.11rc1 Keywords: win32 bbackupd compare checksums force upload | -----------------------------------------------------------+---------------- On Unix, you could touch the files to force bbackupd to compare them and upload again if necessary. Under Windows without cygwin touch this is not possible. In any case it would be good to have a mechanism to force bbackupd to compare each file, not just the ones that it thinks have changed, and upload a patch if necessary. -- Ticket URL: Box Backup An open source, completely automatic on-line backup system for UNIX. From boxbackup-dev at boxbackup.org Sun Nov 23 01:21:33 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 23 Nov 2008 01:21:33 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2383 - box Message-ID: <20081123012133.BBD33325021@www.boxbackup.org> Author: jamesog Date: 2008-11-23 01:21:31 +0000 (Sun, 23 Nov 2008) New Revision: 2383 Added: box/snapshots/ Log: Create directory for tagging snapshots From boxbackup-dev at boxbackup.org Sun Nov 23 01:25:10 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 23 Nov 2008 01:25:10 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2384 - box/snapshots Message-ID: <20081123012510.4E49E325021@www.boxbackup.org> Author: jamesog Date: 2008-11-23 01:25:09 +0000 (Sun, 23 Nov 2008) New Revision: 2384 Added: box/snapshots/0.11_trunk_2368/ Log: Create tag for October 2008 snapshot From boxbackup-dev at boxbackup.org Sun Nov 23 15:52:44 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 23 Nov 2008 15:52:44 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2385 - in box/trunk: . infrastructure Message-ID: <20081123155244.49B1E325021@www.boxbackup.org> Author: jamesog Date: 2008-11-23 15:52:43 +0000 (Sun, 23 Nov 2008) New Revision: 2385 Modified: box/trunk/infrastructure/makeparcels.pl.in box/trunk/parcels.txt Log: Hook the man pages into the build/install system. Man pages are now included in the client and server parcels and installed to $prefix/man. Modified: box/trunk/infrastructure/makeparcels.pl.in =================================================================== --- box/trunk/infrastructure/makeparcels.pl.in 2008-11-23 01:25:09 UTC (rev 2384) +++ box/trunk/infrastructure/makeparcels.pl.in 2008-11-23 15:52:43 UTC (rev 2385) @@ -110,11 +110,19 @@ { print MAKE "\tfind release debug -type f -exec rm -f {} \\;\n"; } +print MAKE "\trm -rf docs/*.[58] docs/bb-man.xsl docs/man\n" if $product_version =~ /trunk_[0-9]+/; print MAKE "\n"; print MAKE "test:\trelease/common/test\n\nrelease/common/test:\n\t./runtest.pl ALL release\n\n"; +print MAKE < #52: Unable to control the maintenance of old vs. deleted files -------------------------------------------------------------------------+-- Reporter: chris | Owner: chris Type: defect | Status: new Priority: major | Milestone: 0.12 Component: bbackupd | Version: trunk Keywords: backup old deleted housekeeping disk space cleanup snapshot | -------------------------------------------------------------------------+-- Tom Albers writes: Recently I had to retrieve an older version of a folder, but I could not because there were no older versions available. Running info resulted in the following: {{{ Account ID: 00000001 Last object ID: 8009785 Blocks used: 51199878 (99999.76Mb) Blocks used by old files: 0 (0.00Mb) Blocks used by deleted files: 27961849 (54612.99Mb) Blocks used by directories: 233209 (455.49Mb) Block soft limit: 51200000 (100000.00Mb) Block hard limit: 64000000 (125000.00Mb) Client store marker: 1226809601724028 }}} So all space is occupied by current files and deleted files. As stuff moves pretty quickly on that server, a lot of info goes to the deleted section. But part of that is not interesting anymore, but it is kept in the backup for ever. Would it be possible to say: I want 20GB for deleted, 20GB for old and 60GB for current? Or would it be possible to purge the deleted files if they are deleted longer then a week ago? -- Ticket URL: Box Backup An open source, completely automatic on-line backup system for UNIX. From boxbackup-dev at boxbackup.org Mon Nov 24 22:52:17 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Mon, 24 Nov 2008 22:52:17 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2386 - box/trunk/test/bbackupd Message-ID: <20081124225217.C1B1B325FCB@www.boxbackup.org> Author: chris Date: 2008-11-24 22:52:16 +0000 (Mon, 24 Nov 2008) New Revision: 2386 Modified: box/trunk/test/bbackupd/testbbackupd.cpp Log: Fix permissions on restored files after test, so that test build system stops complaining that it can't delete them. Modified: box/trunk/test/bbackupd/testbbackupd.cpp =================================================================== --- box/trunk/test/bbackupd/testbbackupd.cpp 2008-11-23 15:52:43 UTC (rev 2385) +++ box/trunk/test/bbackupd/testbbackupd.cpp 2008-11-24 22:52:16 UTC (rev 2386) @@ -2089,9 +2089,13 @@ #ifdef WIN32 TEST_THAT(::system("chmod 0755 testfiles/" "TestDir1/x1") == 0); + TEST_THAT(::system("chmod 0755 testfiles/" + "restore1/x1") == 0); #else TEST_THAT(chmod("testfiles/TestDir1/x1", 0755) == 0); + TEST_THAT(chmod("testfiles/restore1/x1", + 0755) == 0); #endif } From boxbackup-dev at boxbackup.org Mon Nov 24 23:53:27 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Mon, 24 Nov 2008 23:53:27 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2387 - box/trunk/docs Message-ID: <20081124235327.2C555325FCB@www.boxbackup.org> Author: jamesog Date: 2008-11-24 23:53:26 +0000 (Mon, 24 Nov 2008) New Revision: 2387 Modified: box/trunk/docs/Makefile Log: Fix docs Makefile on non-BSD systems. Modified: box/trunk/docs/Makefile =================================================================== --- box/trunk/docs/Makefile 2008-11-24 22:52:16 UTC (rev 2386) +++ box/trunk/docs/Makefile 2008-11-24 23:53:26 UTC (rev 2387) @@ -8,14 +8,6 @@ MANXSL=bb-man.xsl HTMLPREFIX=box-html VPATH= adminguide -# If your OS declares a system make variable, add a .elif statement here -# with the path to the locally-installed DocBook stylesheet -.if .FreeBSD -# Requires textproc/docbook-xsl port installed -DOCBOOK=file:///usr/local/share/xsl/docbook/manpages/docbook.xsl -.else -DOCBOOK=http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl -.endif .SUFFIXES: .html .xml .1 .5 .8 all: docs @@ -42,7 +34,12 @@ manpages: $(MANXSL) man-dirs man-nroff man-html $(MANXSL): $(MANXSL).tmpl - @sed -e 's,%%DOCBOOK%%,$(DOCBOOK),' $(MANXSL).tmpl > $(MANXSL) + @if [ -f /usr/local/share/xsl/docbook/manpages/docbook.xsl ]; then \ + DOCBOOK=file:///usr/local/share/xsl/docbook/manpages/docbook.xsl; \ + else \ + DOCBOOK=http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl; \ + fi; \ + sed -e "s,%%DOCBOOK%%,$${DOCBOOK}," $(MANXSL).tmpl > $(MANXSL) man-dirs: man/.there $(HTMLPREFIX)/man-html/.there From boxbackup-dev at boxbackup.org Sun Nov 30 21:53:15 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 30 Nov 2008 21:53:15 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2388 - box/trunk/lib/win32 Message-ID: <20081130215315.6828F32502C@www.boxbackup.org> Author: chris Date: 2008-11-30 21:53:14 +0000 (Sun, 30 Nov 2008) New Revision: 2388 Added: box/trunk/lib/win32/getopt_long.cpp Removed: box/trunk/lib/win32/getopt_long.cxx Log: Cygwin/MinGW getopt no longer seems to have optreset, so now would be the time to start using that implementation we stole from BSD. Copied: box/trunk/lib/win32/getopt_long.cpp (from rev 2387, box/trunk/lib/win32/getopt_long.cxx) =================================================================== --- box/trunk/lib/win32/getopt_long.cpp (rev 0) +++ box/trunk/lib/win32/getopt_long.cpp 2008-11-30 21:53:14 UTC (rev 2388) @@ -0,0 +1,550 @@ +/* $OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $ */ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ +// Adapted for Box Backup by Chris Wilson + +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +// #include "Box.h" + +#include +#include +#include +#include +#include + +#include "getopt.h" + +#if defined _MSC_VER || defined __MINGW32__ +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ +#endif + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static void warnx(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + const char * oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + if (posixly_correct == -1) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + else if (*options == '-') + flags |= FLAG_ALLARGS; + if (*options == '+' || *options == '-') + options++; + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + optchar == (int)'-' && *place != '\0' || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } else if (!(flags & FLAG_PERMUTE)) { + /* + * If permutation is disabled, we can accept an + * optional arg separated by whitespace so long + * as it does not start with a dash (-). + */ + if (optind + 1 < nargc && *nargv[optind + 1] != '-') + optarg = nargv[++optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} + Property changes on: box/trunk/lib/win32/getopt_long.cpp ___________________________________________________________________ Added: svn:executable + * Added: svn:mergeinfo + Deleted: box/trunk/lib/win32/getopt_long.cxx =================================================================== --- box/trunk/lib/win32/getopt_long.cxx 2008-11-24 23:53:26 UTC (rev 2387) +++ box/trunk/lib/win32/getopt_long.cxx 2008-11-30 21:53:14 UTC (rev 2388) @@ -1,550 +0,0 @@ -/* $OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $ */ -/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ -// Adapted for Box Backup by Chris Wilson - -/* - * Copyright (c) 2002 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -// #include "Box.h" - -#include -#include -#include -#include -#include - -#include "getopt.h" - -#if defined _MSC_VER || defined __MINGW32__ -#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ -#endif - -#ifdef REPLACE_GETOPT -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ -#endif - -#define PRINT_ERROR ((opterr) && (*options != ':')) - -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ - -/* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 - -#define EMSG "" - -static void warnx(const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - fprintf(stderr, "\n"); -} - -static int getopt_internal(int, char * const *, const char *, - const struct option *, int *, int); -static int parse_long_options(char * const *, const char *, - const struct option *, int *, int); -static int gcd(int, int); -static void permute_args(int, int, int, char * const *); - -static char *place = EMSG; /* option letter processing */ - -/* XXX: set optreset to 1 rather than these two */ -static int nonopt_start = -1; /* first non option argument (for permute) */ -static int nonopt_end = -1; /* first option after non options (for permute) */ - -/* Error messages */ -static const char recargchar[] = "option requires an argument -- %c"; -static const char recargstring[] = "option requires an argument -- %s"; -static const char ambig[] = "ambiguous option -- %.*s"; -static const char noarg[] = "option doesn't take an argument -- %.*s"; -static const char illoptchar[] = "unknown option -- %c"; -static const char illoptstring[] = "unknown option -- %s"; - -/* - * Compute the greatest common divisor of a and b. - */ -static int -gcd(int a, int b) -{ - int c; - - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } - - return (b); -} - -/* - * Exchange the block from nonopt_start to nonopt_end with the block - * from nonopt_end to opt_end (keeping the same order of arguments - * in each block). - */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; - - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; - - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; - /* LINTED const cast */ - ((char **)nargv)[cstart] = swap; - } - } -} - -/* - * parse_long_options -- - * Parse long options in argc/argv argument vector. - * Returns -1 if short_too is set and the option does not match long_options. - */ -static int -parse_long_options(char * const *nargv, const char *options, - const struct option *long_options, int *idx, int short_too) -{ - char *current_argv, *has_equal; - size_t current_argv_len; - int i, match; - - current_argv = place; - match = -1; - - optind++; - - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; - - if (strlen(long_options[i].name) == current_argv_len) { - /* exact match */ - match = i; - break; - } - /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ - if (short_too && current_argv_len == 1) - continue; - - if (match == -1) /* partial match */ - match = i; - else { - /* ambiguous abbreviation */ - if (PRINT_ERROR) - warnx(ambig, (int)current_argv_len, - current_argv); - optopt = 0; - return (BADCH); - } - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { - if (PRINT_ERROR) - warnx(noarg, (int)current_argv_len, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - return (BADARG); - } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else if (long_options[match].has_arg == - required_argument) { - /* - * optional argument doesn't use next nargv - */ - optarg = nargv[optind++]; - } - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ - if (PRINT_ERROR) - warnx(recargstring, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - --optind; - return (BADARG); - } - } else { /* unknown option */ - if (short_too) { - --optind; - return (-1); - } - if (PRINT_ERROR) - warnx(illoptstring, current_argv); - optopt = 0; - return (BADCH); - } - if (idx) - *idx = match; - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - return (0); - } else - return (long_options[match].val); -} - -/* - * getopt_internal -- - * Parse argc/argv argument vector. Called by user level routines. - */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx, int flags) -{ - const char * oli; /* option letter list index */ - int optchar, short_too; - static int posixly_correct = -1; - - if (options == NULL) - return (-1); - - /* - * Disable GNU extensions if POSIXLY_CORRECT is set or options - * string begins with a '+'. - */ - if (posixly_correct == -1) - posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - else if (*options == '-') - flags |= FLAG_ALLARGS; - if (*options == '+' || *options == '-') - options++; - - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (optind == 0) - optind = optreset = 1; - - optarg = NULL; - if (optreset) - nonopt_start = nonopt_end = -1; -start: - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set optind - * to the first of them. - */ - optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - if (*(place = nargv[optind]) != '-' || - (place[1] == '\0' && strchr(options, '-') == NULL)) { - place = EMSG; /* found non-option */ - if (flags & FLAG_ALLARGS) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - optarg = nargv[optind++]; - return (INORDER); - } - if (!(flags & FLAG_PERMUTE)) { - /* - * If no permutation wanted, stop parsing - * at first non-option. - */ - return (-1); - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - nonopt_start = optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = optind; - - /* - * If we have "-" do nothing, if "--" we are done. - */ - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - optind++; - place = EMSG; - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - } - - /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() - */ - if (long_options != NULL && place != nargv[optind] && - (*place == '-' || (flags & FLAG_LONGONLY))) { - short_too = 0; - if (*place == '-') - place++; /* --foo long option */ - else if (*place != ':' && strchr(options, *place) != NULL) - short_too = 1; /* could be short option too */ - - optchar = parse_long_options(nargv, options, long_options, - idx, short_too); - if (optchar != -1) { - place = EMSG; - return (optchar); - } - } - - if ((optchar = (int)*place++) == (int)':' || - optchar == (int)'-' && *place != '\0' || - (oli = strchr(options, optchar)) == NULL) { - /* - * If the user specified "-" and '-' isn't listed in - * options, return -1 (non-option) as per POSIX. - * Otherwise, it is an unknown option character (or ':'). - */ - if (optchar == (int)'-' && *place == '\0') - return (-1); - if (!*place) - ++optind; - if (PRINT_ERROR) - warnx(illoptchar, optchar); - optopt = optchar; - return (BADCH); - } - if (long_options != NULL && optchar == 'W' && oli[1] == ';') { - /* -W long-option */ - if (*place) /* no space */ - /* NOTHING */; - else if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else /* white space */ - place = nargv[optind]; - optchar = parse_long_options(nargv, options, long_options, - idx, 0); - place = EMSG; - return (optchar); - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++optind; - } else { /* takes (optional) argument */ - optarg = NULL; - if (*place) /* no white space */ - optarg = place; - /* XXX: disable test for :: if PC? (GNU doesn't) */ - else if (oli[1] != ':') { /* arg not optional */ - if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else - optarg = nargv[optind]; - } else if (!(flags & FLAG_PERMUTE)) { - /* - * If permutation is disabled, we can accept an - * optional arg separated by whitespace so long - * as it does not start with a dash (-). - */ - if (optind + 1 < nargc && *nargv[optind + 1] != '-') - optarg = nargv[++optind]; - } - place = EMSG; - ++optind; - } - /* dump back option letter */ - return (optchar); -} - -#ifdef REPLACE_GETOPT -/* - * getopt -- - * Parse argc/argv argument vector. - * - * [eventually this will replace the BSD getopt] - */ -int -getopt(int nargc, char * const *nargv, const char *options) -{ - - /* - * We don't pass FLAG_PERMUTE to getopt_internal() since - * the BSD getopt(3) (unlike GNU) has never done this. - * - * Furthermore, since many privileged programs call getopt() - * before dropping privileges it makes sense to keep things - * as simple (and bug-free) as possible. - */ - return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); -} -#endif /* REPLACE_GETOPT */ - -/* - * getopt_long -- - * Parse argc/argv argument vector. - */ -int -getopt_long(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE)); -} - -/* - * getopt_long_only -- - * Parse argc/argv argument vector. - */ -int -getopt_long_only(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx) -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE|FLAG_LONGONLY)); -} - From boxbackup-dev at boxbackup.org Sun Nov 30 21:54:55 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 30 Nov 2008 21:54:55 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2389 - box/trunk/lib/win32 Message-ID: <20081130215455.AACE132502C@www.boxbackup.org> Author: chris Date: 2008-11-30 21:54:55 +0000 (Sun, 30 Nov 2008) New Revision: 2389 Modified: box/trunk/lib/win32/emu.cpp box/trunk/lib/win32/emu.h Log: openfile() stores its Windows error code (from GetLastError() or synthetic) in winerrno, to enable better error handling outside. Modified: box/trunk/lib/win32/emu.cpp =================================================================== --- box/trunk/lib/win32/emu.cpp 2008-11-30 21:53:14 UTC (rev 2388) +++ box/trunk/lib/win32/emu.cpp 2008-11-30 21:54:55 UTC (rev 2389) @@ -31,6 +31,8 @@ static bool gFinishTimer; static CRITICAL_SECTION gLock; +DWORD winerrno; + typedef struct { int countDown; @@ -285,11 +287,12 @@ if (len == 0) { + winerrno = GetLastError(); if (logErrors) { ::syslog(LOG_WARNING, "Failed to convert string to wide string: " - "%s", GetErrorMessage(GetLastError()).c_str()); + "%s", GetErrorMessage(winerrno).c_str()); } errno = EINVAL; return NULL; @@ -305,6 +308,7 @@ "Failed to convert string to wide string: " "out of memory"); } + winerrno = ERROR_OUTOFMEMORY; errno = ENOMEM; return NULL; } @@ -321,11 +325,12 @@ if (len == 0) { + winerrno = GetLastError(); if (logErrors) { ::syslog(LOG_WARNING, "Failed to convert string to wide string: " - "%s", GetErrorMessage(GetLastError()).c_str()); + "%s", GetErrorMessage(winerrno).c_str()); } errno = EACCES; delete [] buffer; @@ -519,6 +524,7 @@ "Failed to open '%s': path too long", pFileName); errno = ENAMETOOLONG; + winerrno = ERROR_INVALID_NAME; tmpStr = ""; return tmpStr; } @@ -594,6 +600,8 @@ // -------------------------------------------------------------------------- HANDLE openfile(const char *pFileName, int flags, int mode) { + winerrno = ERROR_INVALID_FUNCTION; + std::string AbsPathWithUnicode = ConvertPathToAbsoluteUnicode(pFileName); @@ -667,7 +675,8 @@ if (hdir == INVALID_HANDLE_VALUE) { - switch(GetLastError()) + winerrno = GetLastError(); + switch(winerrno) { case ERROR_SHARING_VIOLATION: errno = EBUSY; @@ -684,6 +693,7 @@ return INVALID_HANDLE_VALUE; } + winerrno = NO_ERROR; return hdir; } Modified: box/trunk/lib/win32/emu.h =================================================================== --- box/trunk/lib/win32/emu.h 2008-11-30 21:53:14 UTC (rev 2388) +++ box/trunk/lib/win32/emu.h 2008-11-30 21:54:55 UTC (rev 2389) @@ -245,6 +245,7 @@ // local constant to open file exclusively without shared access #define O_LOCK 0x10000 +extern DWORD winerrno; /* used to report errors from openfile() */ HANDLE openfile(const char *filename, int flags, int mode); #define LOG_DEBUG LOG_INFO From boxbackup-dev at boxbackup.org Sun Nov 30 21:56:38 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 30 Nov 2008 21:56:38 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2390 - box/trunk/lib/common Message-ID: <20081130215638.0860C32502C@www.boxbackup.org> Author: chris Date: 2008-11-30 21:56:37 +0000 (Sun, 30 Nov 2008) New Revision: 2390 Modified: box/trunk/lib/common/FileStream.cpp Log: Log the Windows error code if openfile() fails on Windows, as the default strerror() seems borked and reports EBUSY (file in use) as"Resource device". Modified: box/trunk/lib/common/FileStream.cpp =================================================================== --- box/trunk/lib/common/FileStream.cpp 2008-11-30 21:54:55 UTC (rev 2389) +++ box/trunk/lib/common/FileStream.cpp 2008-11-30 21:56:37 UTC (rev 2390) @@ -73,8 +73,13 @@ } else { + #ifdef WIN32 + BOX_LOG_WIN_WARNING("Failed to open file: " << + mFileName); + #else BOX_LOG_SYS_WARNING("Failed to open file: " << mFileName); + #endif THROW_EXCEPTION(CommonException, OSFileOpenError) } } From boxbackup-dev at boxbackup.org Sun Nov 30 22:00:24 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 30 Nov 2008 22:00:24 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2391 - box/trunk/lib/common Message-ID: <20081130220024.0E1EC32502C@www.boxbackup.org> Author: chris Date: 2008-11-30 22:00:23 +0000 (Sun, 30 Nov 2008) New Revision: 2391 Modified: box/trunk/lib/common/FileStream.cpp box/trunk/lib/common/Logging.h Log: Compile fix and log the error number recorded by winerrno, not the "last" error, whatever that was. Modified: box/trunk/lib/common/FileStream.cpp =================================================================== --- box/trunk/lib/common/FileStream.cpp 2008-11-30 21:56:37 UTC (rev 2390) +++ box/trunk/lib/common/FileStream.cpp 2008-11-30 22:00:23 UTC (rev 2391) @@ -74,8 +74,8 @@ else { #ifdef WIN32 - BOX_LOG_WIN_WARNING("Failed to open file: " << - mFileName); + BOX_LOG_WIN_WARNING_NUMBER("Failed to open file: " << + mFileName, winerrno); #else BOX_LOG_SYS_WARNING("Failed to open file: " << mFileName); Modified: box/trunk/lib/common/Logging.h =================================================================== --- box/trunk/lib/common/Logging.h 2008-11-30 21:56:37 UTC (rev 2390) +++ box/trunk/lib/common/Logging.h 2008-11-30 22:00:23 UTC (rev 2391) @@ -61,8 +61,12 @@ #ifdef WIN32 #define BOX_LOG_WIN_ERROR(stuff) \ BOX_ERROR(stuff << ": " << GetErrorMessage(GetLastError())) + #define BOX_LOG_WIN_WARNING(stuff) \ + BOX_WARNING(stuff << ": " << GetErrorMessage(GetLastError())) #define BOX_LOG_WIN_ERROR_NUMBER(stuff, number) \ BOX_ERROR(stuff << ": " << GetErrorMessage(number)) + #define BOX_LOG_WIN_WARNING_NUMBER(stuff, number) \ + BOX_WARNING(stuff << ": " << GetErrorMessage(number)) #endif #define BOX_FORMAT_HEX32(number) \ From boxbackup-dev at boxbackup.org Sun Nov 30 22:24:29 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 30 Nov 2008 22:24:29 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2392 - box/trunk/lib/win32 Message-ID: <20081130222429.0455D32502C@www.boxbackup.org> Author: chris Date: 2008-11-30 22:24:28 +0000 (Sun, 30 Nov 2008) New Revision: 2392 Modified: box/trunk/lib/win32/emu.cpp Log: Fix support for O_APPEND on files opened with openfile() on Windows. Modified: box/trunk/lib/win32/emu.cpp =================================================================== --- box/trunk/lib/win32/emu.cpp 2008-11-30 22:00:23 UTC (rev 2391) +++ box/trunk/lib/win32/emu.cpp 2008-11-30 22:24:28 UTC (rev 2392) @@ -693,6 +693,18 @@ return INVALID_HANDLE_VALUE; } + if (flags & O_APPEND) + { + if (SetFilePointer(hdir, 0, NULL, FILE_END) == + INVALID_SET_FILE_POINTER) + { + winerrno = GetLastError(); + errno = EINVAL; + CloseHandle(hdir); + return INVALID_HANDLE_VALUE; + } + } + winerrno = NO_ERROR; return hdir; } From boxbackup-dev at boxbackup.org Sun Nov 30 22:25:27 2008 From: boxbackup-dev at boxbackup.org (boxbackup-dev at boxbackup.org) Date: Sun, 30 Nov 2008 22:25:27 +0000 (GMT) Subject: [Box Backup-commit] COMMIT r2393 - box/trunk/bin/bbackupquery Message-ID: <20081130222527.C109332502C@www.boxbackup.org> Author: chris Date: 2008-11-30 22:25:27 +0000 (Sun, 30 Nov 2008) New Revision: 2393 Modified: box/trunk/bin/bbackupquery/bbackupquery.cpp Log: Add support for using the logging framework to log (most) bbackupquery output to a file, with its own verbosity level. Modified: box/trunk/bin/bbackupquery/bbackupquery.cpp =================================================================== --- box/trunk/bin/bbackupquery/bbackupquery.cpp 2008-11-30 22:24:28 UTC (rev 2392) +++ box/trunk/bin/bbackupquery/bbackupquery.cpp 2008-11-30 22:25:27 UTC (rev 2393) @@ -62,10 +62,13 @@ #ifdef WIN32 "[-u] " #endif - "\n\t[-c config_file] [-l log_file] [commands]\n" + "\n" + "\t[-c config_file] [-o log_file] [-O log_file_level]\n" + "\t[-l protocol_log_file] [commands]\n" + "\n" "As many commands as you require.\n" "If commands are multiple words, remember to enclose the command in quotes.\n" - "Remember to use quit command if you don't want to drop into interactive mode.\n"); + "Remember to use the quit command unless you want to end up in interactive mode.\n"); exit(1); } @@ -118,12 +121,15 @@ #endif #ifdef WIN32 - const char* validOpts = "qvwuc:l:W:"; + const char* validOpts = "qvwuc:l:o:O:W:"; bool unicodeConsole = false; #else - const char* validOpts = "qvwc:l:W:"; + const char* validOpts = "qvwc:l:o:O:W:"; #endif + std::string fileLogFile; + Log::Level fileLogLevel = Log::INVALID; + // See if there's another entry on the command line int c; while((c = getopt(argc, (char * const *)argv, validOpts)) != -1) @@ -187,6 +193,22 @@ } break; + case 'o': + fileLogFile = optarg; + fileLogLevel = Log::EVERYTHING; + break; + + case 'O': + { + fileLogLevel = Logging::GetNamedLevel(optarg); + if (fileLogLevel == Log::INVALID) + { + BOX_FATAL("Invalid logging level"); + return 2; + } + } + break; + #ifdef WIN32 case 'u': unicodeConsole = true; @@ -204,6 +226,12 @@ Logging::SetGlobalLevel((Log::Level)masterLevel); + std::auto_ptr fileLogger; + if (fileLogLevel != Log::INVALID) + { + fileLogger.reset(new FileLogger(fileLogFile, fileLogLevel)); + } + bool quiet = false; if (masterLevel < Log::NOTICE) {