#!/usr/pkg/bin/perl -w
# CD-R(W) restore utility
# Copyright (C) 2001 John-Paul Gignac
#
# 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Id: cdrstr.in,v 1.5 2002/02/28 12:34:22 bubuchka Exp $

$prefix = '/usr/pkg';
$exec_prefix = "${prefix}";
$sbindir = "${exec_prefix}/sbin";

$cdcat = "${sbindir}/cdcat";
$ssh = '/usr/bin/ssh';
$gnutar = '/usr/pkg/bin/gtar';
$rgnutar = $gnutar;

sub esc_shell {
	$_ = shift;
	s/([^-.\/_a-zA-Z0-9])/\\$1/g;
	return $_;
}

sub usage {
	print
	"cdrstr performs a full or incremental restore of a filesystem\n".
	"from CD-Rs.\n".
	"\n".
	"Usage: $0 [OPTION]... TARGETDIR\n".
	"Options:\n".
	" --help              Show this help message\n".
	" -c, --compress=TYPE Set decompression to one of gz|bz2|none. Default: gz\n".
	" -d, --device=PATH   Specify the CD-ROM device (default: /dev/cdrom)\n".
	" -h, --host=HOST     Specify the hostname for remote restore\n".
	" -p, --prefix=NAME   Specify the filename prefix (default: '')\n".
	" -t, --test          Get files from the current directory instead of the CD\n".
	" -z, --zip-here      For remote restores, perform decompression locally\n".
	" -V, --version       Show version info\n";
	exit 1;
}

# Option defaults
$compress = "gz";
$device = "/dev/cdrom";
$remotehost = "";
$prefix = "";
$test = 0;
$ziphere = 0;

# Parse the options
while( scalar @ARGV) {
	$_ = shift;
	if( substr( $_, 0, 1) ne '-') {
		unshift( @ARGV, $_);
		last;
	}

	$i = index( $_, '=');
	if( $i > 0) {
		unshift( @ARGV, substr( $_, $i+1));
		$_ = substr( $_, 0, $i);
	}

	if( $_ eq '--') {
		last;
	} elsif( $_ eq '-c' || $_ eq '--compress') {
		$compress = shift;
		die "Unknown compression format: $compress\n"
			if($compress ne 'gz' && $compress ne 'bz2' && $compress ne 'none');
	} elsif( $_ eq '-d' || $_ eq '--device') {
		$device = shift;
	} elsif( $_ eq '-h' || $_ eq '--host') {
		$remotehost = shift;
		die "Invalid hostname: $remotehost\n"
			if( $remotehost =~ /[^-._a-zA-Z0-9]/);
	} elsif( $_ eq '-p' || $_ eq '--prefix') {
		$prefix = shift;
	} elsif( $_ eq '-t' || $_ eq '--test') {
		$test = 1;
	} elsif( $_ eq '-z' || $_ eq '--zip-here') {
		$ziphere = 1;
	} elsif( $_ eq '-V' || $_ eq '--version') {
		print "cdrstr-" . '1.0' . "\n";
		exit 0;
	} else {
		usage();
	}
}
usage() if( scalar @ARGV != 1);
$targetdir = shift;

sub remotize {
	$cmd = shift;
	return "$ssh $remotehost ".esc_shell($cmd) if( $remotehost ne '');
	return $cmd;
}

# We don't ignore ziphere even if remote host still undefined. This
# workaround useful for old GNU tars which not supported "-j" option yet.

if( $remotehost ne '') {
	# Use relative path for remote tar
	$rgnutar = "tar";
}

die "$0: $targetdir: target directory is not accessible.\n"
	unless ( -d $targetdir );

$tarcmd = "cd ".esc_shell($targetdir)." && ";
$tarcmd .= "$rgnutar -f - -x";
unless( $ziphere) {
	$tarcmd .= "z" if( $compress eq 'gz');
	$tarcmd .= "j" if( $compress eq 'bz2');
}	
$tarcmd .= " --incremental";

$tarcmd = remotize( $tarcmd);
$tarcmd = "($tarcmd)";

if( $ziphere) {
	$tarcmd = "/usr/bin/gzip -d | $tarcmd" if( $compress eq 'gz');
	$tarcmd = "/usr/bin/bzip2 -d | $tarcmd" if( $compress eq 'bz2');
}

$options = "--device=".esc_shell($device);
$options .= " --prefix=".esc_shell($prefix);
$options .= " --test" if( $test);
if( system( "$cdcat $options | $tarcmd") != 0) {
	exit 1;
}
