#!/usr/bin/perl # Copyright (C) 2009 Neil Williams # # This package 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 3 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, see . use Config::Auto; use File::Basename; use strict; use vars qw/ $progname $ourversion %scripts $dstrap $script $extra @archives $deb $cachedir $config_str %packages $retval $str $retries $dir $include $arch $foreign $suite $url $forceunpack $option %options @e $sourcesname $libdir $dpkgdir @debootstrap %suites $mirror $etcdir $repo @dirs @touch %sources $section %keys $host $key $value $type $file $config /; $progname = basename($0); while( @ARGV ) { $_= shift( @ARGV ); last if m/^--$/; if (!/^-/) { unshift(@ARGV,$_); last; } elsif (/^(-\?|-h|--help|--version)$/) { &usageversion(); exit( 0 ); } elsif (/^(-f|--file)$/) { $file = shift(@ARGV); } elsif (/^(-a|--arch)$/) { $arch = shift(@ARGV); } else { die "$progname: Unknown option $_.\n"; } } die ("Need a configuration file - use $progname -f\n") if (not defined $file); $config = Config::Auto::parse("$file"); %keys=(); foreach $key (%$config) { $type = lc($key) if (ref $key ne "HASH"); $value = $key if (ref $key eq "HASH"); $keys{$type} = $value; } %sources=(); %packages=(); %suites=(); %options=(); %scripts=(); foreach $section (sort keys %keys) { if ($section eq "general") { $arch = $keys{$section}{'arch'} if (not defined $arch); $retries = $keys{$section}{'retries'}; $dir = $keys{$section}{'directory'}; $forceunpack = lc($keys{$section}{'forceunpack'}); @debootstrap = split(' ', lc($keys{$section}{'debootstrap'})); } else { $sources{$section}=$keys{$section}{'source'}; $packages{$section}=$keys{$section}{'packages'}; $suites{$section}=$keys{$section}{'suite'}; $scripts{$section}=$keys{$section}{'script'}; $options{$section}=$keys{$section}{'options'}; } } $host = `dpkg-architecture -qDEB_BUILD_ARCH`; chomp ($host); $foreign = ($host ne $arch) ? "--foreign" : ''; $cachedir = "var/cache/apt/"; # archives $libdir = "var/lib/apt/"; # lists $etcdir = "etc/apt/"; # sources $dpkgdir = "var/lib/dpkg/"; # state mkdir ("$dir") if (not -d "$dir"); system ("mkdir -p ${dir}${cachedir}"); system ("mkdir -p ${dir}${libdir}"); system ("mkdir -p ${dir}${dpkgdir}"); system ("mkdir -p ${dir}etc/apt/sources.list.d/"); @dirs = qw/ alternatives info parts updates/; @touch = qw/ diversion statoverride status lock/; foreach my $dpkgd (@dirs) { if (not -d "${dir}${dpkgdir}$dpkgd") { mkdir "${dir}${dpkgdir}$dpkgd"; } } foreach my $file (@touch) { utime(time, time, "${dir}${dpkgdir}/$file") or ( open(F, ">${dir}${dpkgdir}/$file") && close F ) } unlink ("${dir}etc/apt/sources.list.d/sources.list") if (-f "${dir}etc/apt/sources.list.d/sources.list"); unlink ("${dir}etc/apt/sources.list") if (-f "${dir}etc/apt/sources.list"); foreach $repo (sort keys %suites) { if (not -e "${dir}${cachedir}") { mkdir "${dir}${cachedir}"; } if (not -e "$dir/${libdir}lists") { mkdir "$dir/${libdir}lists"; } if (not -e "$dir/${libdir}lists/partial") { mkdir "$dir/${libdir}lists/partial"; } if (not -e "$dir/${cachedir}archives") { mkdir "$dir/${cachedir}archives"; } if (not -e "$dir/${cachedir}archives/partial") { mkdir "$dir/${cachedir}archives/partial"; } if (-d "${dir}etc/apt/") { open (SOURCES, ">>${dir}etc/apt/sources.list.d/sources.list") or die "Cannot open sources list $!"; $mirror = $sources{$repo}; $suite = $suites{$repo}; print SOURCES< 0) { print "Problem - trying again, $retries left.\n"; sleep 1; $retval = system ("$str"); $retries--; } } if ($forceunpack eq "true") { opendir (DEBS, "${dir}${cachedir}archives/") or die ("Cannot read apt archives directory.\n"); @archives=grep(/.*\.deb$/, readdir DEBS); closedir (DEBS); chdir ("${dir}"); foreach $deb (@archives) { print "Extracting $deb...\n"; system ("ar -p \"./${cachedir}archives/$deb\" data.tar.gz | zcat | tar -xf -"); } } system ("apt-get $config_str update"); sub write_script { ($dstrap) = @_; $extra = $packages{$dstrap}; $script = $scripts{$dstrap}; return if ($script eq ''); open (SCRIPT, ">$script") or die ("Cannot open $script. $!\n"); print SCRIPT<