#!/usr/bin/perl
#
# Script to convert dpkg, rpm, tgz packages.
# Original author:
#   Christoph Lameter, <clameter@debian.org> October 30, 1996
# The deb -> rpm conversion code was written by:
#   Randoph Chung <rc42@cornell.edu>
# Current maintainer:
#   Joey Hess <joeyh@debian.org>
#
# Copyright: GPL

use strict;

# Globals.
use vars qw($desttype $file $filetype $generate $install $workdir $libdir
	$keep_version $scripts $tgzdescription $patchfile $nopatch $single
	$prefix @patchdirs);

BEGIN {
	$prefix="/usr"; # PREFIX_AUTOREPLACE done by Makefile, do not edit.

	# Directory where alien templates, etc, are stored.
	$libdir="$prefix/share/alien";
	push @INC, $libdir;
}

# Directories where alien patches are stored.
@patchdirs=('/var/lib/alien',"$prefix/lib/alien/patches");

use Getopt::Long;

# Load up all of alien's modules.
use Alien;
use Fromrpm;
use Fromdeb;
use Fromtgz;
use Fromslp;
use Torpm;
use Todeb;
use Totgz;
use Toslp;

# Display alien's version number.
sub Version {
	my $version_string='unknown'; # VERSION_AUTOREPLACE done by Makefile, do not edit.
	print "Alien version $version_string\n";
}

# Display usage help.
sub Usage {
	print <<eof;
Usage: alien [options ...] file [...]
  file [...]                Package file or files to convert.
  -d, --to-deb              Generate a Debian deb package. (default)
     Enables the following options:
       --patch=<patch>      Specify patch file to use instead of automatically
                            looking for patch in /var/lib/alien.
       --nopatch	    Do not use patches.
  -r, --to-rpm              Generate a RedHat rpm package.
  -t, --to-tgz              Generate a Slackware tgz package.
      --to-slp              Generate a Stampede .slp package.
  -i, --install             Install generated package.
  -g, --generate            Unpack, but do not generate a new package.
  -s, --single              Like --generate, but do not create .orig directory.
  -c, --scripts             Include scripts in package.
  -k, --keep-version        Do not change version of generated package.
      --description=<desc>  Specify package description.
  -h, --help                Display this help message.
  -v, --version		    Display alien's version number.

eof
}

# Process parameters.
# Sets some global variables.
sub GetParams {
	my ($todeb, $torpm, $totgz, $toslp, $help, $version);

	# Get options.
	my $ret=GetOptions(
		"to-deb|d", \$todeb,
		"to-rpm|r", \$torpm,
		"to-tgz|t", \$totgz,
		"to-slp", \$toslp,
		"generate|g", \$generate,
		"install|i", \$install,
		"single|s", \$single,
		"scripts|c", \$scripts,
		"patch|p=s", \$patchfile,
		"nopatch", \$nopatch,
		"description=s", \$tgzdescription,
		"keep-version|k", \$keep_version,
		"help|h", \$help,
		"version|v", \$version,
	);

	if (!$ret) {
		Usage();
		exit 1;
	}

	if ($version) {
		Version();
		exit 1;
	}

	if ($help) {
		Usage();
		exit;
	}

	if ($single) {
		$generate=1;
	}

	if ($todeb) {
		$desttype='deb'
	}
	elsif ($torpm) {
		$desttype='rpm';
	}
	elsif ($totgz) {
		$desttype='tgz';
	}
	elsif ($toslp) {
		$desttype='slp';
	}
	else {
		$desttype='deb';
	}

	# Sanity check options.
	if ($desttype ne 'deb' && $patchfile) {
		Usage();
		Alien::Error("You can not use --patch with --to-rpm or --to-tgz or --to-slp");
	}
	if (($generate || $single) && $install) {
		Usage();
		Alien::Error("You can not use --generate or --single with --install");
	}
	if ($patchfile && ! -f $patchfile) {
		Alien::Error("Specified patch file, \"$patchfile\" was not be found.");
	}
	if ($patchfile && $nopatch) {
		Alien::Error("The options --nopatch and --patchfile cannot be used together.");
	}

	if (!@ARGV) {
		Usage();
		Alien::Error("You must specify a file to convert.");
	}	
}

# Check alien's working anvironment.
sub TestEnviron() {
	if (! -w '.') {
		Alien::Error("Cannot write to current directory. Try changing to /tmp and re-running alien.");
	}
	if ($> ne 0) {
		if ($desttype eq 'deb' && ! $generate && ! $single) {
			Alien::Error("Must run as root to convert to .deb format (or you may use fakeroot).");
		}
		Alien::Warning("Warning: alien is not running as root!");
		Alien::Warning("Ownerships of files in the generated packages will");
		Alien::Warning("probably be messed up.");
	}
}

# Main program:

# Initialization and data collection.
GetParams();
TestEnviron();

foreach $file (@ARGV) {
	if (! -f $file) {
		Alien::Error("File $file not found.\n");
	}
	$filetype=Alien::FileType($file);
	if ($filetype eq $desttype) {
		Alien::Error("There is no point in converting a $filetype into a $desttype.");
	}
	Alien::Status("Examining $file");

	# These variables are set to let us refer to the proper packages
	# to process the source and destination file types.
	my $dest="To::$desttype";
	my $src="From::$filetype";

	my %fields=$dest->FixFields($src->GetFields($file));

	# Unpack stage.
	Alien::Status("Unpacking $file");
	$workdir="$fields{NAME}-$fields{VERSION}";
	Alien::SafeMkdir($workdir);
	chdir $workdir;
	$src->Unpack($file,%fields);
	chdir "..";

	# Conversion stage.
	$dest->Convert($workdir,$nopatch,%fields);

	# Build stage.
	if (!$generate) {
		my $packagename=$dest->GetPackageName(%fields);
		Alien::Status("Building the package $packagename");
		chdir $workdir;
		$dest->Build(%fields);
		chdir "..";
		Alien::SafeSystem("rm -rf $workdir");
		# The above "building $packagename..." message can get lost in the
		# noise, so tell them again where the package ended up.
		print "\nGeneration of $packagename complete.\n" if !$install;
	}

	# Install stage.
	if ($install) {
		my $packagename=$dest->GetPackageName(%fields);
		Alien::Status("Installing generated $desttype package");
		$dest->Install($packagename);
		unlink $packagename;
	}
}

Alien::Status("Successfully finished");
