mirror of https://github.com/fspc/gbootroot.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
525 lines
15 KiB
525 lines
15 KiB
#!/usr/bin/perl -w
|
|
|
|
# make_debian Copyright (C) 2001 from gBootRoot
|
|
# Lead Developer and Project Coordinator
|
|
# Jonathan Rosenbaum <freesource@users.sourceforge.net>
|
|
#
|
|
# http://gbootroot.sourceforge.net
|
|
|
|
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
use strict;
|
|
use File::Basename;
|
|
|
|
# You will need to get swim at http://www.sourceforge.net/projects/avd
|
|
my $home = "$ENV{HOME}/.gbootroot";
|
|
my $home_yard = "$home/yard";
|
|
my $template_dir = "$home_yard/templates/";
|
|
my $home_yard_replacements = "$home_yard/Replacements";
|
|
my $nodename = `uname -n`; chomp $nodename;
|
|
my $debian_yard = "Debian-$nodename.yard";
|
|
my $status = "/var/lib/dpkg/status";
|
|
my $info = "/var/lib/dpkg/info";
|
|
my (%alternatives, @alternatives); # for checking for alternatives
|
|
my %inetd; # checks for inetd binaries.
|
|
|
|
# You need file-rc, and you may add other extra stuff. These packages were
|
|
# chosen for woody, so you may need something different. If you add stuff,
|
|
# check for dependencies, empty directories and special configuration files
|
|
# created by the package scripts.
|
|
#
|
|
# You may have to edit the text below STUFF.
|
|
#
|
|
# Swim provides excellent information for this task. swim -qT packagename(s) &
|
|
# swim -ql --df packagename(s) & swim -qc packagename(s) (not all conf files
|
|
# can be found this way .. read above) so you will want to use
|
|
# swim -q --scripts packagename(s) or
|
|
# swim -q --preinst --postinst packagenames(s).
|
|
|
|
my @extra_packages = qw(file-rc swim apt apt-utils debconf nvi sysklogd
|
|
klogd netbase tcpd net-tools portmap netkit-ping netkit-inetd ifupdown less
|
|
perl perl-modules libwrap0 ipchains whiptail libnewt0 libpopt0 slang1
|
|
debconf-utils);
|
|
|
|
# And tests will be ran here for file-rc and swim
|
|
# swim has to have its databases made.
|
|
# Options: to include or remove docs /usr/share/{doc,man,info}
|
|
# and other stuff which creates fluff.
|
|
|
|
system "swim --search \"Priority: required\" --no";
|
|
my $swim_packages = "swim -qS|";
|
|
my $swim_list = "swim -qSl|"; # Not using --df for empty directories.
|
|
$, = " ";
|
|
my $extra_files = "swim -ql @extra_packages|"; # Not using --df.
|
|
$, = "";
|
|
|
|
# All the packages
|
|
open(SWIM,$swim_packages) or die "Couldn't open $!\n";
|
|
my @required_packages = <SWIM>; chomp @required_packages;
|
|
close(SWIM);
|
|
|
|
push(@required_packages,@extra_packages);
|
|
|
|
# All the files
|
|
open(SWIM,$swim_list) or die "Couldn't open $!\n";
|
|
my @required_files = <SWIM>; chomp @required_files;
|
|
close(SWIM);
|
|
|
|
open(SWIM,$extra_files) or die "Couldn't open $!\n";
|
|
my @extra_files = <SWIM>; chomp @extra_files;
|
|
close(SWIM);
|
|
|
|
push(@required_files,@extra_files);
|
|
|
|
#################################################################
|
|
#################################################################
|
|
#
|
|
# EDIT
|
|
# BELOW
|
|
#
|
|
# Edit below $stuff = << "STUFF" to make changes to the template.
|
|
sub stuff {
|
|
|
|
my $stuff = << "STUFF";
|
|
# Generated by make_debian.
|
|
|
|
# This template creates a complete Debian system which is more streamlined
|
|
# than the base.tgz used for normal installations. Once everything is made,
|
|
# you can use user-mode-linux to tweak the system, as well as apt.
|
|
# Make-debian generates all the information you need, you will need swim and
|
|
# file-rc installed, and you will have to be running a Debian system to make
|
|
# this template. Make-debian ditches info, man, and doc files by default,
|
|
# use the "doc" option to make documentation.
|
|
|
|
# Characteristics: user: root passwd: root
|
|
# user: user passwd: user
|
|
# Uses devfs.
|
|
|
|
# IMPORTANT NOTE: Things slow down noticeably when the buffer gets too big in
|
|
# the verbosity box so consider closing it with the slider for faster
|
|
# generation. Look at /tmp/verbose instead.
|
|
|
|
# Todays Quote: Creating a root filesystem is all about stuff.
|
|
|
|
# The STUFF NEEDED in order for init to work.
|
|
/etc/runlevel.conf <= Replacements/etc/runlevel.conf # made by make_debian
|
|
/etc/init.d/rc
|
|
/etc/init.d/rcS
|
|
/etc/inittab <= Replacements/etc/inittab.debian # specific to devfs
|
|
/etc/default/rcS
|
|
|
|
# Stuff needed to return init to its state prior to installing file-rc.
|
|
/etc/init.d/rc.links
|
|
/etc/init.d/rcS.links
|
|
/usr/sbin/update-rc.d.links
|
|
|
|
# Login stuff
|
|
/etc/securetty <= Replacements/etc/securetty.debian # devfs needs this
|
|
/root/.bashrc <= Replacements/root/.bashrc.debian
|
|
/root/.profile <= Replacements/root/.profile.debian
|
|
/home/user/.bashrc <= Replacements/home/user/.bashrc.debian
|
|
/home/user/.bash_profile <= Replacements/home/user/.bash_profile.debian
|
|
/home/user/README <= Replacements/home/user/README # permissions issue
|
|
/etc/hostname <= Replacements/etc/hostname
|
|
/etc/motd <= Replacements/etc/motd
|
|
|
|
# Important stuff .. you will need to edit the login files if you add packages
|
|
# which require other users/groups. The default fstab mounts /dev/ubd/0.
|
|
#/etc/fstab <= Replacements/etc/fstab.new # Made from Yard Box menu
|
|
/etc/fstab <= Replacements/etc/fstab.debian # devfs specific
|
|
/etc/passwd <= Replacements/etc/passwd.debian
|
|
/etc/passwd- <= Replacements/etc/passwd-debian
|
|
/etc/group <= Replacements/etc/group.debian
|
|
/etc/group- <= Replacements/etc/group-debian
|
|
/etc/shadow <= Replacements/etc/shadow.debian
|
|
|
|
# The stuff required by dpkg.
|
|
/var/lib/dpkg/diversions <= Replacements/var/lib/dpkg/diversions
|
|
/var/lib/dpkg/cmethopt
|
|
/var/lib/dpkg/lock
|
|
/var/lib/dpkg/status <= Replacements/var/lib/dpkg/status
|
|
/var/lib/dpkg/methods/disk
|
|
/var/lib/dpkg/methods/floppy
|
|
/var/lib/dpkg/methods/mnt
|
|
/var/lib/dpkg/info
|
|
/var/lib/dpkg/updates
|
|
/var/lib/dpkg/alternatives
|
|
/var/lib/dpkg/available <= Replacements/var/lib/dpkg/available
|
|
|
|
# Stuff needed by apt.
|
|
/var/cache/apt/archives/lock
|
|
/var/cache/apt/archives/partial
|
|
/var/lib/apt/lists/lock
|
|
/var/lib/apt/lists/partial
|
|
/etc/apt/*
|
|
|
|
# Debconf stuff
|
|
/var/cache/debconf
|
|
|
|
# Ipchains stuff
|
|
/etc/default/ipchains
|
|
|
|
# Netkit-inetd stuff
|
|
/etc/inetd.conf <= Replacements/etc/inetd.conf
|
|
|
|
# Tcpd stuff
|
|
/etc/hosts.allow
|
|
/etc/hosts.deny
|
|
|
|
# Network stuff
|
|
# You will want to edit the interfaces file.
|
|
# Remember to load any needed modules on the host system, for instance
|
|
# if tap is used, you will want to do this:
|
|
# modprobe ethertap
|
|
# modprobe netlink_dev
|
|
# And when you start your creation with the uml box you will want to add
|
|
# something like this to the options where HWaddr (see ifconfig) belongs
|
|
# to your network device:
|
|
# eth0=ethertap,tap0,HWaddr,192.168.1.5
|
|
/etc/resolv.conf
|
|
/etc/hosts <= Replacements/etc/hosts
|
|
/root/umlnet <= Replacements/root/umlnet # Example network setup script
|
|
/etc/network <= Replacements/etc/network
|
|
/etc/network/if-down.d # empty
|
|
/etc/network/if-post-down.d # ""
|
|
/etc/network/if-pre-up.d # ""
|
|
/etc/network/if-up.d # ""
|
|
/etc/network/interfaces <= Replacements/etc/network/interfaces
|
|
/etc/network/spoof-protect
|
|
|
|
# Devices - optional stuff which can be picked up by devfsd.
|
|
/dev/MAKEDEV # a link
|
|
/dev/mem
|
|
/dev/kmem
|
|
/dev/null
|
|
/dev/zero
|
|
/dev/ram*
|
|
/dev/console
|
|
/dev/tty[0-9]
|
|
/dev/hd[abcd]*
|
|
/dev/ttyS[0-9]
|
|
/dev/fd0*
|
|
/dev/sd*
|
|
#/dev/cdrom
|
|
#/dev/modem
|
|
/dev/pts*
|
|
/dev/ptmx
|
|
/dev/initctl
|
|
/dev/urandom
|
|
/dev/ubd0 <= Replacements/dev/ubd0
|
|
|
|
# Empty directories with no stuff.
|
|
/mnt
|
|
/proc
|
|
/tmp
|
|
/var/tmp
|
|
/var/run
|
|
/var/lock
|
|
/var/log/news
|
|
|
|
# Stuff so ldconfig doesn't complain.
|
|
/etc/ld.so.conf <= Replacements/etc/ld.so.conf
|
|
|
|
## ALL the REQUIRED files generated by make-debian.
|
|
## This is stuff from the required packages, so some files may be
|
|
## removed, or some files can be replaced with stuff from say .. busybox.
|
|
STUFF
|
|
|
|
return $stuff;
|
|
} # end sub stuff
|
|
#################################################################
|
|
#################################################################
|
|
|
|
#######################
|
|
## Template Creation ##
|
|
#######################
|
|
open(DEBIAN,">$template_dir/$debian_yard")
|
|
or die "Couldn't open $!\n";
|
|
open(FILERC,"/etc/runlevel.conf") or die "No runlevel.conf: $!\n";
|
|
my @filerc = <FILERC>;
|
|
close(FILERC);
|
|
|
|
print DEBIAN stuff();
|
|
|
|
my @file_rc;
|
|
alternatives();
|
|
inetd_in();
|
|
foreach (@required_files) {
|
|
if (-e && !-d) {
|
|
if ($ARGV[0] && $ARGV[0] eq "doc") {
|
|
if ($alternatives{$_}) {
|
|
push(@alternatives,$_);
|
|
}
|
|
if ($inetd{$_}) {
|
|
$inetd{$_} = 1;
|
|
}
|
|
print DEBIAN "$_\n";
|
|
}
|
|
else {
|
|
if (! m,/usr/share/info|/usr/share/man|/usr/share/doc,) {
|
|
if ($alternatives{$_}) {
|
|
push(@alternatives,$_);
|
|
}
|
|
if ($inetd{$_}) {
|
|
$inetd{$_} = 1;
|
|
}
|
|
print DEBIAN "$_\n";
|
|
}
|
|
}
|
|
if (m,/etc/init\.d,) {
|
|
foreach my $filerc (@filerc) {
|
|
push(@file_rc,$filerc) if $filerc =~ /$_/;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
inetd_out();
|
|
|
|
print DEBIAN "\n# Scripts associated with packages found in info/*\n";
|
|
print DEBIAN status_info_divert();
|
|
|
|
# alternatives
|
|
print DEBIAN "\n# Alternative stuff.\n";
|
|
foreach (@alternatives) {
|
|
if ($alternatives{$_}) {
|
|
print DEBIAN "/etc/alternatives/", $alternatives{$_}, "\n";
|
|
print DEBIAN "/var/lib/dpkg/alternatives/", $alternatives{$_}, "\n";
|
|
print DEBIAN dirname($_), "/", $alternatives{$_}, "\n";
|
|
}
|
|
}
|
|
|
|
close(DEBIAN);
|
|
|
|
#########################
|
|
# END TEMPLATE CREATION #
|
|
#########################
|
|
|
|
# This creates a tweaked runlevel.conf which is easier then trying to figure
|
|
# out which symlinks to use in /etc/rc?d.
|
|
|
|
open(MY_FILERC,">$home_yard_replacements/etc/runlevel.conf")
|
|
or die "Couldn't open $home_yard_replacements/etc/runlevel.conf: $!\n";
|
|
my @sortedrc = map { $_->[1] }
|
|
sort { $a->[0] <=> $b->[0] }
|
|
map { [ (split(/\s/,$_))[0], $_ ] }
|
|
@file_rc;
|
|
print MY_FILERC @sortedrc;
|
|
close(MY_FILERC);
|
|
|
|
# This creates a status file for use by dpkg and swim.
|
|
# Although swim could be used to do this, it is more efficient just to
|
|
# parse the status file. But because this is a good exercise for
|
|
# using this script to create a status file found from packages on a system
|
|
# which doesn't actually have a status file .. here would be the order
|
|
# needed when using swim to query:
|
|
#
|
|
# Package, Status, Priority, Section, Installed-Size, Maintainer, Source,
|
|
# Version, Replaces, Provides, Depends, Pre-Depends, Recommends, Suggests,
|
|
# Conflicts, Conffiles, Description.
|
|
#
|
|
# Conffiles would have to be handled both before and after Root Filesystem
|
|
# creation so that their md5sums could be accounted for in status.
|
|
#
|
|
# And this finds all the scripts associated with a package in info/*,
|
|
# creates an empty available file, and creates the diversions file.
|
|
|
|
sub status_info_divert {
|
|
|
|
$/ = "";
|
|
open(STATUS,"$status") or die "Can't find /var/lib/dpkg/status: $!\n";
|
|
home_builder("$home_yard_replacements/var/lib/dpkg");
|
|
system "touch $home_yard_replacements/var/lib/dpkg/available";
|
|
#or die "Couldn't create Replacements/var/lib/dpkg/available: $!\n";
|
|
open(NEW_STATUS,">$home_yard_replacements/var/lib/dpkg/status")
|
|
or die "Couldn't open $home_yard_replacements/var/lib/dpkg/status: $!\n";
|
|
while (<STATUS>) { # keep the order
|
|
my $stat = $_;
|
|
my $stat2 = (split(/\n/,$stat))[0]; # might as well
|
|
foreach my $rp (@required_packages) {
|
|
$rp = (split(/_/,$rp))[0];
|
|
# Deal with names with +
|
|
$rp =~ s/\+/\\+/g if $rp !~ /\\+/g;
|
|
if ($stat2 =~ /^Package: $rp$/) {
|
|
print NEW_STATUS $stat;
|
|
}
|
|
}
|
|
}
|
|
close(NEW_STATUS);
|
|
close(STATUS);
|
|
$/ = "\n";
|
|
|
|
my %dpkg_divert;
|
|
my $dpkg_divert = "dpkg-divert --list|";
|
|
open(DIVERT,"$dpkg_divert")
|
|
or die "Couldn't find the dpkg-divert command: $!\n";
|
|
while (<DIVERT>) {
|
|
|
|
my($original,$diversion,$package) = (split(" "))[2,4,6];
|
|
chomp $package;
|
|
if (!$dpkg_divert{$package}) { # Just add to the array
|
|
$dpkg_divert{$package} = [$original,$diversion];
|
|
}
|
|
else {
|
|
push @{ $dpkg_divert {$package} }, $original, $diversion;
|
|
}
|
|
|
|
}
|
|
close(DIVERT) or die "Couldn't close: $!\n";
|
|
|
|
open(DIVERT,">$home_yard_replacements/var/lib/dpkg/diversions")
|
|
or die "Couldn't open Replacements/var/lib/dpkg/diversions: $!\n";
|
|
my @info;
|
|
foreach my $rp (@required_packages) {
|
|
$rp = (split(/_/,$rp))[0];
|
|
# Get rid of the escapes from the previous invocation.
|
|
$rp =~ s/\\//g if $rp =~ /\\+/g;
|
|
|
|
my $count = 0; my @divert;
|
|
if ($dpkg_divert{$rp}) {
|
|
foreach my $dv ( @{ $dpkg_divert{$rp} } ) {
|
|
push(@divert,$dv);
|
|
if ($count == 1) {
|
|
print DIVERT "$divert[0]\n";
|
|
print DIVERT "$divert[1]\n";
|
|
print DIVERT "$rp\n";
|
|
$count = -1; undef @divert;
|
|
}
|
|
$count++;
|
|
}
|
|
}
|
|
|
|
# Figure out info/* .. this covers it for now.
|
|
if (-f "$info/$rp.preinst") {
|
|
push(@info,"$info/$rp.preinst\n");
|
|
}
|
|
if (-f "$info/$rp.postinst") {
|
|
push(@info,"$info/$rp.postinst\n");
|
|
}
|
|
if (-f "$info/$rp.prerm") {
|
|
push(@info,"$info/$rp.prerm\n");
|
|
}
|
|
if (-f "$info/$rp.postrm") {
|
|
push(@info,"$info/$rp.postrm\n");
|
|
}
|
|
if (-f "$info/$rp.list") {
|
|
push(@info,"$info/$rp.list\n");
|
|
}
|
|
if (-f "$info/$rp.shlibs") {
|
|
push(@info,"$info/$rp.shlibs\n");
|
|
}
|
|
if (-f "$info/$rp.conffiles") {
|
|
push(@info,"$info/$rp.conffiles\n");
|
|
}
|
|
if (-f "$info/$rp.md5sums") {
|
|
push(@info,"$info/$rp.md5sums\n");
|
|
}
|
|
if (-f "$info/$rp.config") {
|
|
push(@info,"$info/$rp.config\n");
|
|
}
|
|
}
|
|
close(DIVERT);
|
|
|
|
return @info;
|
|
|
|
} # end sub status_info_divert
|
|
|
|
sub alternatives {
|
|
|
|
my $ls = "ls -l /etc/alternatives|";
|
|
my @ls;
|
|
open(LS,$ls) or die "No ls?: $!\n";
|
|
while (<LS>) {
|
|
if (/->/) {
|
|
my($left,$right) = split(" -> ");
|
|
chomp $right;
|
|
$left =~ s/^.*\d+\s//g;
|
|
$alternatives{$right} = $left;
|
|
}
|
|
}
|
|
close(LS);
|
|
|
|
} # end sub alternatives
|
|
|
|
sub inetd_in {
|
|
|
|
my $inetd = "/etc/inetd.conf";
|
|
open(INETD,"$inetd") or return "Couldn't open /etc/inetd.conf: $!\n";
|
|
# Basically will ignore anything with less than 7 columns, and
|
|
# will comment lines where the executables don't exist.
|
|
while (<INETD>) {
|
|
if ( (split(/\s+/))[6] && !/^#.*/ ) {
|
|
my $seventh_column = (split(/\s+/))[6];
|
|
chomp $seventh_column;
|
|
$inetd{ basename($seventh_column) } = 0;
|
|
}
|
|
}
|
|
close(INETD);
|
|
|
|
}
|
|
|
|
sub inetd_out {
|
|
|
|
my $inetd = "/etc/inetd.conf";
|
|
open(REP_INETD,">$home_yard_replacements/etc/inetd.conf")
|
|
or return "Couldn't open Replacements/etc/inetd.conf: $!\n";
|
|
open(INETD,"$inetd") or return "Couldn't open /etc/inetd.conf: $!\n";
|
|
while (<INETD>) {
|
|
if ( (split(/\s+/))[6] && !/^#.*/ ) {
|
|
my $seventh_column = (split(/\s+/))[6];
|
|
chomp $seventh_column;
|
|
if ( $inetd{ basename($seventh_column) } == 1 ) {
|
|
print REP_INETD $_;
|
|
}
|
|
else {
|
|
print REP_INETD "# $_";
|
|
}
|
|
}
|
|
else {
|
|
print REP_INETD $_;
|
|
}
|
|
}
|
|
close(REP_INETD);
|
|
close(INETD);
|
|
|
|
}
|
|
|
|
sub home_builder {
|
|
|
|
my ($home_builder) = @_;
|
|
|
|
if (!-d $home_builder) {
|
|
if (-e $home_builder) {
|
|
print "ERROR: A file exists where $home_builder should be.\n";
|
|
}
|
|
else {
|
|
my @directory_parts = split(m,/,,$home_builder);
|
|
my $placement = "/";
|
|
for (1 .. $#directory_parts) {
|
|
$_ == 1 ? ($placement = "/$directory_parts[$_]")
|
|
: ($placement = $placement . "/" . $directory_parts[$_]);
|
|
-d $placement or mkdir $placement;
|
|
}
|
|
}
|
|
}
|
|
|
|
} # end home_builder
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|