[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: Forcing RH9 floppy kickstart to full duplex.
- From: Ronald Reed <rreed ops sgp arm gov>
- To: kickstart-list redhat com
- Subject: Re: Forcing RH9 floppy kickstart to full duplex.
- Date: 21 May 2003 17:51:18 -0500
Use this script. You can add the e100 module to the boot floppy. I used
it to create a custom boot floppy for pcmica network cards, since the
laptops that I needed to install on had pcmcia floppy drives that
disappeared upon boot.
Ron
On Wed, 2003-05-21 at 15:18, Anderson, Bill wrote:
> I might be outta luck on this one, but here goes anyway...
>
> I've put the following into my ks.cfg just before the network line:
>
> device ethernet e100 --opts "e100_speed_duplex=4"
>
> However, when this file is read, the driver e100 can't be loaded because
> it
> is on the driver-floppy I'm going to insert in a matter of seconds.
> When
> the e100 driver is read off that floppy, the attempt to force to
> full-duplex
> is nullified.
>
> I realize that floppy-based kickstart is going the way of the dinosaur
> and
> eight-track tapes, but unfortunately for me, moving to CD-ROM based
> kickstart isn't an option right now. I also realize that if I could set
> the
> switch I'm plugged into to auto-negotiate, then all would be fine and
> dandy.
> However, I have no control over the settings of the switches.
>
> I read a few threads ago about how to access a network based ks.cfg
> w/out
> DHCP, but I haven't had time to investigate that one yet. I also read a
> while ago about suggestions for hacking the RH9 kickstart down to one
> floppy; that doesn't work for me either. As for my original question,
> I'm
> just wondering if there's any hope for what I'm trying to do today.
> Thanks
> to all...
>
> Bill
>
> Bill Anderson
> TDS Telecom ISS
>
>
> _______________________________________________
> Kickstart-list mailing list
> Kickstart-list redhat com
> https://www.redhat.com/mailman/listinfo/kickstart-list
--
===========================
Ron Reed
Unix Systems Administrator
ARM SGP CART Site
(580)388-4053
ron reed arm gov
#!/usr/bin/perl -w
#
# Copyright (c) 2003
# Chris Adams <cmadams iruntheinter 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.
########################################################################
#
# Add and/or delete modules from the base Red Hat Linux bootdisk (using the
# drvnet and drvblock driver disks). This will also modify the PCI table so
# that an alternate module is used (like replacing sym53c8xx with
# sym53c8xx_2), and can optionally replace the kernel and modules with new
# versions from a kernel-BOOT-*.rpm.
#
# Command line options:
# -q - quiet mode
# -a <module>[,<module>...] - module(s) to add
# -d <module>[,<module>...] - module(s) to remove
# -i <directory> - original disk image directory
# -k <kernel-BOOT.rpm> - new kernel boot RPM to replace kernel/modules
# -o <file> - output image file name
# -r <omod=nmod>[,<omod2=nmod2>...] - replace omod with nmod in pcitable
# -u <glob>[,<glob>...] - unlink files matching glob on bootdisk
#
# Requires:
# coreutils
# cpio
# e2fsprogs
# losetup
# mount
# perl
# perl-Compress-Zlib
# rpm
#
# History:
# 1.0 - 2003-04-26
# initial version
#
# 1.1 - 2003-04-28
# when replacing kernel, rename module directory too
#
# 1.2 - 2003-05-01
# add error handling clean-ups
# allow adding additional modules (like RAID) from supplied kernel RPM
# add option to unlink files from bootdisk to make more space for initrd
# make sure new initrd fits onto floppy
#
use Getopt::Std;
use File::Temp qw(tempdir);
use File::Copy;
use File::Path;
use Compress::Zlib;
use POSIX qw(mkfifo);
use Fcntl qw(:mode);
use strict;
# Get and check options
die "Must be run as root\n" if ($> != 0);
my $SIZE = 3000;
use vars qw($opt_i $opt_a $opt_d $opt_o $opt_r $opt_k $opt_q $opt_u);
$opt_i = ".";
$opt_a = $opt_d = $opt_r = $opt_k = $opt_q = $opt_u = "";
$opt_o = "custom.img";
getopts ("i:a:d:o:r:k:qu:");
my @add = split (/,/, $opt_a);
my @del = split (/,/, $opt_d);
die "Nothing to add or delete\n" if (! @add && ! @del);
die "Output image already exists\n" if (-e $opt_o);
die "Can't find kernel update RPM\n" if ($opt_k && ! -e $opt_k);
die "Can't find RHL images directory\n" if (! -e $opt_i);
my $base = $opt_i . "/bootdisk.img";
my %drv = ();
$drv{"net"} = $opt_i . "/drvnet.img";
$drv{"block"} = $opt_i . "/drvblock.img";
$drv{"pcmcia"} = $opt_i . "/pcmciadd.img";
die "Can't find RHL images\n"
if (! (-e $base && -e $drv{"net"} && -e $drv{"block"} && -e $drv{"pcmcia"}));
my %replace = ();
foreach my $pair (split (/,/, $opt_r)) {
my ($old, $new) = split (/=/, $pair);
die "Invalid replace pair \"$pair\"\n" if (! $old || ! $new);
$replace{$new} = $old;
}
# Variables to keep track of things to clean-up
use vars qw(@mounts $tdir);
@mounts = ();
$tdir = "";
$SIG{"__DIE__"} = sub {
warn @_;
debug ("Cleaning up\n");
foreach my $mount (reverse @mounts) {
debug ("Unmounting ", $mount, "\n");
umount ($mount);
}
debug ("Removing ", $tdir, "\n");
rmtree ($tdir) if ($tdir);
debug ("Removing ", $opt_o, "\n");
unlink ($opt_o);
exit 1;
};
# Make a workspace and mount the bootdisk
debug ("Mounting bootdisk\n");
copy ($base, $opt_o) or die "copy($base,$opt_o): $!\n";
$tdir = tempdir ("modXXXXXXXX");
my $bootmnt = $tdir . "/bootdisk";
mkdir ($bootmnt) or die "mkdir($bootmnt): $!\n";
mount ("-orw,loop", $opt_o, $bootmnt);
# Remove the specified files
if ($opt_u) {
unlink (map { glob ($bootmnt . "/" . $_) } (split (/,/, $opt_u)));
}
# Uncompress the initrd image and make a copy of the tree
my $initrd = $tdir . "/initrd.img";
system("cp $bootmnt/initrd.img $initrd.gz");
system("gunzip $initrd.gz");
#open (INITRD, "> $initrd") or die "open(>$initrd): $!\n";
#my $gz = gzopen ($bootmnt . "/initrd.img", "r")
# or die "gzopen($bootmnt/initrd.img): $gzerrno\n";
#my $buf;
#while ($gz->gzread ($buf)) {
# print INITRD $buf;
#}
#close (INITRD);
#$gz->gzclose;
debug ("Mounting original initrd\n");
my $initmnt = $tdir . "/initrd";
mkdir ($initmnt) or die "mkdir($initmnt): $!\n";
mount ("-oro,loop", $initrd, $initmnt);
debug ("Copying initrd\n");
my $newinit = $tdir . "/newinit";
mkdir ($newinit) or die "mkdir($newinit): $!\n";
copydir ($initmnt, $newinit);
umount ($initmnt);
rmdir ($initmnt);
unlink ($initrd);
debug ("Extracting initrd modules\n");
my $initmod = $tdir . "/mod-init";
mkdir ($initmod) or die "mkdir($initmod): $!\n";
cgzextract ($newinit . "/modules/modules.cgz", $initmod);
# Mount the net and block driver images and extract the modules
foreach my $d (qw(net block pcmcia)) {
debug ("Mounting ", $d, " disk\n");
my $img = $drv{$d};
my $imgmnt = $tdir . "/drv" . $d;
mkdir ($imgmnt) or die "mkdir($imgmnt): $!\n";
mount ("-oro,loop", $img, $imgmnt);
debug ("Extracting ", $d, " modules\n");
my $imgmod = $tdir . "/mod-" . $d;
mkdir ($imgmod) or die "mkdir($imgmod): $!\n";
cgzextract ($imgmnt . "/modules.cgz", $imgmod);
}
# Find the kernel version and inventory all the modules and dependencies
opendir (IMOD, $initmod) or die "opendir($initmod): $!\n";
my $kver = "";
while (defined (my $e = readdir (IMOD))) {
next if ($e =~ /^\.{1,2}$/);
if ($e =~ /^\d+\.\d+\.\d+-\d+BOOT$/) {
$kver = $e;
last;
}
}
closedir (IMOD);
die "Can't figure kernel version\n" if (! $kver);
debug ("Taking module inventory\n");
my %mods = ();
foreach my $d (qw(init net block pcmcia)) {
my $dir = $tdir . "/mod-" . $d . "/" . $kver;
opendir (MOD, $dir) or die "opendir($dir) $!\n";
while (defined (my $e = readdir (MOD))) {
my ($mod) = $e =~ /(.+)\.o$/;
next if (! $mod);
$mods{$mod} = $dir . "/" . $e;
}
closedir (MOD);
}
my %deps = my %info = my %pci = my %special = ();
foreach my $d (qw(newinit/modules drvnet drvblock drvpcmcia)) {
debug ("Reading module info in ", $d, "\n");
my $dir = $tdir . "/" . $d;
open (DEP, "$dir/modules.dep") or die "open($dir/modules.dep): $!\n";
while (<DEP>) {
chomp;
my ($mod, $dep) = $_ =~ /^(\S+): (.+)$/;
$deps{$mod} = $dep;
}
close (DEP);
my $info = "";
foreach my $file (qw(modinfo module-info)) {
my $f = $dir . "/" . $file;
if (-f $f) {
$info = $f;
last;
}
}
die "Can't find module info in $d\n" if (! $info);
open (INFO, $info) or die "open($info): $!\n";
my $ver = <INFO>;
chomp $ver;
die "Unknown info version $ver\n" if ($ver ne "Version 0");
my $mod = "";
while (<INFO>) {
if (/^\S/) {
$mod = $_;
chomp $mod;
$info{$mod} = $_;
} else {
$info{$mod} .= $_;
}
}
close (INFO);
open (PCI, "$dir/pcitable") or die "open($dir/pcitable): $!\n";
while (<PCI>) {
chomp;
my ($id, $mod, $desc) = $_ =~ /^(.+\s+")([^"]+)("\s+".+")$/;
$pci{$mod}{$id} = $desc;
if ($d eq "newinit/modules") {
$special{$mod} = 1;
}
}
close (PCI);
}
foreach my $d (qw(net block pcmcia)) {
debug ("Unmounting ", $d, "\n");
my $dir = $tdir . "/drv" . $d;
umount ($dir);
rmdir ($dir);
}
# Now actually add and remove modules and regenerate info files
my $mdir = $tdir . "/mod-init/" . $kver;
foreach my $mod (@del) {
debug ("Removing ", $mod, "\n");
my $f = $mdir . "/" . $mod . ".o";
if (-e $f) {
unlink ($f) or die "unlink($f): $!\n";
} else {
warn "Can't remove $mod (doesn't exist) - skipping\n";
}
}
my %add = map { $_ => 1 } @add;
foreach my $mod (@add) {
next if (! $deps{$mod});
my @dep = split (/\s+/, $deps{$mod});
foreach my $dep (@dep) {
my $f = $mdir . "/" . $dep . ".o";
next if (-e $f);
$add{$dep} = 1;
debug ("Adding dependency on ", $dep, "\n");
}
}
@add = sort keys %add;
my @toadd = ();
foreach my $mod (@add) {
debug ("Adding ", $mod, "\n");
my $f = $mdir . "/" . $mod . ".o";
if (! $mods{$mod}) {
if ($opt_k) {
# Module may be found in new kernel RPM
warn "Skipping $mod - will look in kernel RPM\n";
push @toadd, $mod;
next;
}
die "Unknown module $mod\n";
}
if (-e $f) {
warn "Skipping adding $mod - already exists\n";
} else {
my ($atime, $mtime) = (stat ($mods{$mod}))[8,9];
copy ($mods{$mod}, $f) or die "copy($mods{$mod},$f): $!\n";
utime ($atime, $mtime, $f);
}
}
my @mods = ();
opendir (MDIR, $mdir) or die "opendir($mdir): $!\n";
while (defined (my $e = readdir (MDIR))) {
next if ($e =~ /^\.{1,2}$/);
my ($mod) = $e =~ /^(.+)\.o$/;
push @mods, $mod;
}
closedir (MDIR);
debug ("Creating new modules.dep\n");
open (DEP, ">$newinit/modules/modules.dep")
or die "open(>$newinit/modules/modules.dep): $!\n";
foreach my $mod (sort @mods) {
if (defined ($deps{$mod})) {
print DEP $mod, ": ", $deps{$mod}, "\n";
}
}
close (DEP);
debug ("Creating new module-info\n");
open (INFO, ">$newinit/modules/module-info")
or die "open(>$newinit/modules/module-info): $!\n";
print INFO "Version 0\n";
foreach my $mod (sort @mods) {
if (defined ($info{$mod})) {
print INFO $info{$mod};
}
}
close (INFO);
debug ("Creating new pcitable\n");
open (PCI, ">$newinit/modules/pcitable")
or die "open(>$newinit/modules/pcitable): $!\n";
foreach my $mod (sort (keys %special, @mods)) {
my $m = $mod;
$m = $replace{$mod} if ($replace{$mod});
foreach my $id (sort keys %{$pci{$m}}) {
print PCI $id, $mod, $pci{$m}{$id}, "\n";
}
}
close (PCI);
debug ("Removing original module trees\n");
rmtree ($tdir . "/mod-net") or die "rmtree($tdir/mod-net): $!\n";
rmtree ($tdir . "/mod-block") or die "rmtree($tdir/mod-block): $!\n";
rmtree ($tdir . "/mod-pcmcia") or die "rmtree($tdir/mod-pcmcia): $!\n";
# If there is a new kernel to use, replace the files now
if ($opt_k) {
debug ("Extracting new kernel RPM\n");
my $kdir = $tdir . "/kern";
mkdir ($kdir) or die "mkdir($kdir): $!\n";
die "fork(rpm): $!\n" unless defined (my $pid = open (RPM, "-|"));
if (! $pid) {
open (STDIN, "</dev/null");
open (STDERR, ">/dev/null");
exec "/usr/bin/rpm2cpio", $opt_k
or die "exec(rpm): $!\n";
}
die "fork(cpio): $!\n" unless defined ($pid = open (CPIO, "-|"));
if (! $pid) {
chdir ($kdir);
open (STDIN, "<&RPM") or die "dup(RPM): $!\n";
open (STDERR, ">&STDOUT") or die "dup(STDOUT): $!\n";
exec "/bin/cpio", "-dumi" or die "exec(cpio): $!\n";
}
close (RPM);
my $res = join ("", <CPIO>);
close (CPIO);
die "rpm2cpio failed: \"$res\"\n" if (($? >>8) != 0);
debug ("Taking inventory of new kernel modules\n");
my $nkmod = $kdir . "/lib/modules";
opendir (NK, $nkmod) or die "opendir($nkmod): $!\n";
my $nkver = "";
while (defined (my $e = readdir (NK))) {
next if ($e =~ /^\.{1,2}$/);
if ($e =~ /^\d+\.\d+\.\d+-[a-zA-Z0-9\.]+$/) {
$nkver = $e;
last;
}
}
closedir (NK);
die "Can't figure new kernel version\n" if (! $nkver);
$nkmod .= "/" . $nkver . "/kernel";
# Find all the module files in the new kernel tree and replace them in
# the modules tree
use File::Find;
my %nmod= ();
find ({"wanted" => sub { $nmod{$1} = $_ if (/([^\/]+)\.o$/) },
"no_chdir" => 1}, $nkmod);
debug ("Replacing modules\n");
foreach my $mod (@mods) {
die "Can't find new module \"$mod\"\n" if (! $nmod{$mod});
my $mfile = $mdir . "/" . $mod . ".o";
copy ($nmod{$mod}, $mfile)
or die "copy($nmod{$mod},$mfile): $!\n";
}
if (@toadd) {
debug ("Adding modules from kernel RPM\n");
foreach my $mod (@toadd) {
die "Unknown module $mod\n" if (! $nmod{$mod});
my $mfile = $mdir . "/" . $mod . ".o";
copy ($nmod{$mod}, $mfile)
or die "copy($nmod{$mod},$mfile): $!\n";
push @mods, $mod;
}
}
debug ("Replacing kernel\n");
my $nkern = $kdir . "/boot/vmlinuz-" . $nkver;
my $okern = $bootmnt . "/vmlinuz";
copy ($nkern, $okern) or die "copy($nkern,$okern): $!\n";
debug ("Removing new kernel RPM tree\n");
rmtree ($kdir) or die "rmtree($kdir): $!\n";
my $nmdir = $tdir . "/mod-init/" . $nkver;
rename ($mdir, $nmdir) or die "rename($mdir,$nmdir): $!\n";
$kver = $nkver;
$mdir = $nmdir;
}
# Make the new modules.cgz
debug ("Building modules.cgz\n");
my $cgz = gzopen ($newinit . "/modules/modules.cgz", "w9")
or die "gzopen($newinit/modules/modules.cgz): $gzerrno\n";
pipe (FILELIST, TOCPIO) or die "pipe: $!\n";
die "fork(cpio): $!\n" unless defined (my $pid = open (SUB, "-|"));
if (! $pid) {
chdir ($tdir . "/mod-init");
open (STDIN, "<&FILELIST") or die "dup(FILELIST): $!\n";
close (FILELIST);
close (TOCPIO);
open (STDERR, ">/dev/null");
exec "/bin/cpio", "-oa", "-Hcrc" or die "exec(cpio): $!\n";
}
close (FILELIST);
print TOCPIO map { $kver . "/" . $_ . ".o\n" } @mods;
close (TOCPIO);
my $cbuf;
while (sysread (SUB, $cbuf, 4096)) {
$cgz->gzwrite ($cbuf);
}
close (SUB);
die "cpio failed\n" if (($? >> 8) != 0);
$cgz->gzclose;
debug ("Removing new module tree\n");
rmtree ($tdir . "/mod-init") or die "rmtree($tdir/mod-init): $!\n";
# Make the new initrd
debug ("Creating new initrd\n");
my $lodev = `echo findlodev | /sbin/nash --quiet`;
chomp $lodev;
die "Can't find available loopback device\n" if (! $lodev);
my $lofile = $tdir . "/newinit.img";
open (LO, ">$lofile") or die "open(>$lofile): $!\n";
print LO "\0" x ($SIZE * 1024);
close (LO);
die "fork(losetup): $!\n" unless defined ($pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec "/sbin/losetup", $lodev, $lofile or die "exec(losetup): $!\n";
}
my $res = join ("", <SUB>);
close (SUB);
die "losetup failed: \"$res\"\n" if (($? >> 8) != 0);
pipe (YES, TOMKFS) or die "pipe: $!\n";
die "fork(mke2fs): $!\n" unless defined ($pid = open (SUB, "-|"));
if (! $pid) {
open (STDIN, "<&YES") or die "dup(FILELIST): $!\n";
close (YES);
close (TOMKFS);
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec "/sbin/mke2fs", $lodev, $SIZE or die "exec(mke2fs): $!\n";
}
close (YES);
print TOMKFS "y\n";
close (TOMKFS);
$res = join ("", <SUB>);
close (SUB);
die "mke2fs failed: \"$res\"\n" if (($? >> 8) != 0);
die "fork(tune2fs): $!\n" unless defined ($pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec "/sbin/tune2fs", "-i0", "-c0", $lodev
or die "exec(tune2fs): $!\n";
}
$res = join ("", <SUB>);
close (SUB);
die "tune2fs failed: \"$res\"\n" if (($? >> 8) != 0);
my $lomnt = $tdir . "/newinit-mnt";
mkdir ($lomnt) or die "mkdir($lomnt): $!\n";
mount ("-text2", "-orw", $lodev, $lomnt);
rmdir ($newinit . "/lost+found");
copydir ($newinit, $lomnt);
rmtree ($newinit) or die "rmtree($newinit): $!\n";
umount ($lomnt);
rmdir ($lomnt);
die "fork(losetup): $!\n" unless defined ($pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec "/sbin/losetup", "-d", $lodev or die "exec(losetup): $!\n";
}
$res = join ("", <SUB>);
close (SUB);
die "losetup failed: \"$res\"\n" if (($? >> 8) != 0);
debug ("Compressing new initrd\n");
my $newimg = $tdir . "/initrd.img";
my $igz = gzopen ($newimg, "w9")
or die "gzopen($newimg): $gzerrno\n";
open (LO, "$lofile") or die "open($lofile): $!\n";
my $ibuf;
while (sysread (LO, $ibuf, 4096)) {
$igz->gzwrite ($ibuf);
}
close (LO);
$igz->gzclose;
unlink ($lofile);
debug ("new initrd size: ", (stat ($newimg))[7], "\n");
copy ($newimg, $bootmnt . "/initrd.img")
or die "copy($newimg,$bootmnt/initrd.img): $!\n";
unlink ($newimg);
debug ("Cleaning up\n");
umount ($bootmnt);
rmdir ($bootmnt);
rmdir ($tdir);
# Print debug messages
sub debug
{
print STDERR @_ if (! $opt_q);
}
# Call out to mount, die on failure
sub mount
{
use vars qw($mount_bin);
if (! $mount_bin) {
# Find it
foreach my $d (qw(/usr/sbin /sbin /usr/bin /bin)) {
if (-e $d . "/mount") {
$mount_bin = $d . "/mount";
last;
}
}
die "Can't find mount\n" if (! $mount_bin);
}
local (*SUB);
die "fork(mount): $!\n" unless defined (my $pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec $mount_bin, @_ or die "exec(mount): $!\n";
}
my $out = join ("", <SUB>);
close (SUB);
die "mount failed: \"$out\"\n" if (($? >> 8) != 0);
push @mounts, $_[$#_];
}
# Call out to umount, die on failure
sub umount
{
use vars qw($umount_bin);
if (! $umount_bin) {
# Find it
foreach my $d (qw(/usr/sbin /sbin /usr/bin /bin)) {
if (-e $d . "/umount") {
$umount_bin = $d . "/umount";
last;
}
}
die "Can't find umount\n" if (! $umount_bin);
}
# Need to take this dir out of list first in case we die
my $dir = $_[$#_];
@mounts = grep { $_ ne $dir } @mounts;
local (*SUB);
die "fork(umount): $!\n" unless defined (my $pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec $umount_bin, @_ or die "exec(umount): $!\n";
}
my $out = join ("", <SUB>);
close (SUB);
die "umount failed: \"$out\"\n" if (($? >> 8) != 0);
}
# Copy a directory tree from one place to another
sub copydir
{
my $src = shift;
my $dst = shift;
my %inodes;
local (*SRC);
opendir (SRC, $src) or die "opendir($src): $!\n";
while (defined (my $e = readdir (SRC))) {
next if ($e =~ /^\.{1,2}$/);
my $s = $src . "/" . $e;
my $d = $dst . "/" . $e;
my ($dev, $ino, $mode, $uid, $gid, $rdev, $atime, $mtime) =
(lstat $s)[0,1,2,4,5,6,8,9];
if (defined ($inodes{$dev}{$ino})) {
link ($inodes{$dev}{$ino}, $d)
or die "link($d): $!\n";
} elsif (S_ISREG ($mode)) {
copy ($s, $d) or die "copy($s,$d): $!\n";
chmod ($mode, $d) or die "chmod($d): $!\n";
chown ($uid, $gid, $d) or die "chown($d): $!\n";
utime ($atime, $mtime, $d) or die "utime($d): $!\n";
} elsif (S_ISDIR ($mode)) {
mkdir ($d, $mode) or die "mkdir($d): $!\n";
chown ($uid, $gid, $d) or die "chown($d): $!\n";
copydir ($s, $d);
utime ($atime, $mtime, $d) or die "utime($d): $!\n";
} elsif (S_ISFIFO ($mode)) {
mkfifo ($d);
chmod ($mode, $d) or die "chmod($d): $!\n";
chown ($uid, $gid, $d) or die "chown($d): $!\n";
utime ($atime, $mtime, $d) or die "utime($d): $!\n";
} elsif (S_ISLNK ($mode)) {
my $lnk = readlink ($s);
symlink ($lnk, $d) or die "symlink($d): $!\n";
lchown ($uid, $gid, $d);
} elsif (S_ISBLK ($mode)) {
mknod ($d, "b", $rdev >> 8, $rdev & 0xff);
chmod ($mode, $d) or die "chmod($d): $!\n";
chown ($uid, $gid, $d) or die "chown($d): $!\n";
utime ($atime, $mtime, $d) or die "utime($d): $!\n";
} elsif (S_ISCHR ($mode)) {
mknod ($d, "c", $rdev >> 8, $rdev & 0xff);
chmod ($mode, $d) or die "chmod($d): $!\n";
chown ($uid, $gid, $d) or die "chown($d): $!\n";
utime ($atime, $mtime, $d) or die "utime($d): $!\n";
} else {
die "copydir: can't handle type for $s\n";
}
}
closedir (SRC);
}
# Make a device node
sub mknod
{
use vars qw($mknod_bin);
if (! $mknod_bin) {
# Find it
foreach my $d (qw(/usr/sbin /sbin /usr/bin /bin)) {
if (-e $d . "/mknod") {
$mknod_bin = $d . "/mknod";
last;
}
}
die "Can't find mknod\n" if (! $mknod_bin);
}
local (*SUB);
die "fork(mknod): $!\n" unless defined (my $pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec $mknod_bin, @_ or die "exec(mknod): $!\n";
}
my $out = join ("", <SUB>);
close (SUB);
die "mknod failed: \"$out\"\n" if (($? >> 8) != 0);
}
# Change ownership on a symlink
sub lchown
{
my $uid = shift;
my $gid = shift;
local (*SUB);
die "fork(chown): $!\n" unless defined (my $pid = open (SUB, "-|"));
if (! $pid) {
open (STDERR, ">&STDOUT") or die "dup: $!\n";
exec "/bin/chown", "-h", $uid . ":" . $gid, @_
or die "exec(chown): $!\n";
}
my $out = join ("", <SUB>);
close (SUB);
die "chown failed: \"$out\"\n" if (($? >> 8) != 0);
}
# Extract a cgz file to a given directory
sub cgzextract
{
my $cgz = shift;
my $dir = shift;
my $gz = gzopen ($cgz, "r") or die "gzopen($cgz): $gzerrno\n";
local (*SUB);
die "fork(cpio): $!\n" unless defined (my $pid = open (SUB, "|-"));
if (! $pid) {
chdir ($dir);
open (STDOUT, ">/dev/null");
open (STDERR, ">/dev/null");
exec "/bin/cpio", "-dumi" or die "exec(cpio): $!\n";
}
my $buf;
while ($gz->gzread ($buf)) {
print SUB $buf;
}
$gz->gzclose;
close (SUB);
die "cpio failed\n" if (($? >> 8) != 0);
}
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]