diff options
Diffstat (limited to 'perl-install/commands.pm')
-rw-r--r-- | perl-install/commands.pm | 385 |
1 files changed, 303 insertions, 82 deletions
diff --git a/perl-install/commands.pm b/perl-install/commands.pm index 8448a9f24..e2d0f4c0d 100644 --- a/perl-install/commands.pm +++ b/perl-install/commands.pm @@ -1,16 +1,29 @@ -package commands; +#-######################################################################## +#- This file implement many common shell commands: +#- true, false, cat, which, dirname, basename, rmdir, lsmod, grep, tr, +#- mount, umount, mkdir, mknod, ln, rm, chmod, chown, mkswap, swapon, +#- swapoff, ls, cp, ps, dd, head, tail, strings, hexdump, more, insmod, +#- modprobe, route, df, kill, lspci, lssbus, dmesg, sort, du, +#-######################################################################## +package commands; # $Id$ use diagnostics; use strict; use vars qw($printable_chars); +#-###################################################################################### +#- misc imports +#-###################################################################################### use common qw(:common :file :system :constant); +#-##################################################################################### +#- Globals +#-##################################################################################### my $BUFFER_SIZE = 1024; -1; - - +#-###################################################################################### +#- Functions +#-###################################################################################### sub getopts { my $o = shift; my @r = map { '' } (@_ = split //, $_[0]); @@ -23,6 +36,8 @@ sub getopts { @r; } +sub true { exit 0 } +sub false { exit 1 } sub cat { @ARGV = @_; print while <> } sub which { ARG: foreach (@_) { foreach my $c (split /:/, $ENV{PATH}) { -x "$c/$_" and print("$c/$_\n"), next ARG; }}} sub dirname_ { print dirname(@_), "\n" } @@ -30,13 +45,15 @@ sub basename_ { print basename(@_), "\n" } sub rmdir_ { foreach (@_) { rmdir $_ or die "rmdir: can't remove $_\n" } } sub lsmod { print "Module Size Used by\n"; cat("/proc/modules"); } -sub grep_ { - my ($h, $v) = getopts(\@_, qw(hv)); - my $r = shift and !$h or die "usage: grep <regexp> [files...]\n"; - @ARGV = @_; (/$r/ ? $v || print : $v && print) while <> +sub grep_ { + my ($h, $v, $i) = getopts(\@_, qw(hvi)); + @_ == 0 || $h and die "usage: grep <regexp> [files...]\n"; + my $r = shift; + $r = qr/$r/i if $i; + @ARGV = @_; (/$r/ ? $v || print : $v && print) while <> } -sub tr_ { +sub tr_ { my ($s, $c, $d) = getopts(\@_, qw(s c d)); @_ >= 1 + (!$d || $s) or die "usage: tr [-c] [-s [-d]] <set1> <set2> [files...]\n or tr [-c] -d <set1> [files...]\n"; my $set1 = shift; @@ -47,25 +64,32 @@ sub tr_ { sub mount { @_ or return cat("/proc/mounts"); - my ($t) = getopts(\@_, qw(t)); - my $fs = $t ? shift : $_[0] =~ /:/ ? "nfs" : "ext2"; + my ($t, $r) = getopts(\@_, qw(tr)); + my $fs = $t && shift; - @_ == 2 or die "usage: mount [-t <fs>] <device> <dir>\n", + @_ == 2 or die "usage: mount [-r] [-t <fs>] <device> <dir>\n", + " (use -r for readonly)\n", " (if /dev/ is left off the device name, a temporary node will be created)\n"; - require 'fs.pm'; - fs::mount(@_, $fs, 0, 1); + my ($dev, $where) = @_; + $fs ||= $where =~ /:/ ? "nfs" : + $dev =~ /fd/ ? "vfat" : "ext2"; + + require fs; + require modules; + modules::load_deps("/modules/modules.dep"); + fs::mount($dev, $where, $fs, $r); } sub umount { @_ == 1 or die "umount expects a single argument\n"; - require 'fs.pm'; + require fs; fs::umount($_[0]); } -sub mkdir_ { - my $rec; $_[0] eq '-p' and $rec = shift; +sub mkdir_ { + my ($rec) = getopts(\@_, qw(p)); my $mkdir; $mkdir = sub { my $root = dirname $_[0]; @@ -75,48 +99,42 @@ sub mkdir_ { $rec or die "mkdir: $root does not exist (try option -p)\n"; &$mkdir($root); } + $rec and -d $_[0] and return; mkdir $_[0], 0755 or die "mkdir: error creating directory $_: $!\n"; }; - foreach (@_) { &$mkdir($_); } + &$mkdir($_) foreach @_; } sub mknod { if (@_ == 1) { - require 'devices.pm'; + require devices; eval { devices::make($_[0]) }; $@ and die "mknod: failed to create $_[0]\n"; } elsif (@_ == 4) { - require 'c.pm'; + require c; my $mode = $ {{"b" => c::S_IFBLK(), "c" => c::S_IFCHR()}}{$_[1]} or die "unknown node type $_[1]\n"; syscall_('mknod', my $a = $_[0], $mode | 0600, makedev($_[2], $_[3])) or die "mknod failed: $!\n"; } else { die "usage: mknod <path> [b|c] <major> <minor> or mknod <path>\n"; } } sub ln { - my ($force, $soft, $i); - - while ($i = shift) { - if ($i eq '-f') { $force = 1; } - elsif ($i eq '-s') { $soft = 1; } - elsif ($i eq '-fs' || $i eq '-sf') { $force = $soft = 1; } - else { last } - } + my ($force, $soft) = getopts(\@_, qw(fs)); + @_ >= 1 or die "usage: ln [-s] [-f] <source> [<dest>]\n"; - my $source = $i or die "usage: ln [-s] [-f] <source> [<dest>]\n"; - my $dest = shift || basename($source); + my ($source, $dest) = @_; + $dest ||= basename($source); $force and unlink $dest; - ($soft ? symlink($source, $dest) : link($source, $dest)) or die "ln failed: $!\n"; } -sub rm { - my $rec; $_[0] eq '-r' and $rec = shift; - +sub rm { + my ($rec, undef) = getopts(\@_, qw(rf)); + my $rm; $rm = sub { foreach (@_) { - if (-d $_) { + if (!-l $_ && -d $_) { $rec or die "$_ is a directory\n"; &$rm(glob_($_)); rmdir $_ or die "can't remove directory $_: $!\n"; @@ -126,7 +144,7 @@ sub rm { &$rm(@_); } -sub chmod_ { +sub chmod_ { @_ >= 2 or die "usage: chmod <mode> <files>\n"; my $mode = shift; @@ -136,7 +154,7 @@ sub chmod_ { } sub chown_ { - my $rec; $_[0] eq '-r' and $rec = shift; + my ($rec, undef) = getopts(\@_, qw(r)); local $_ = shift or die "usage: chown [-r] name[.group] <files>\n"; my ($name, $group) = (split('\.'), $_); @@ -154,20 +172,18 @@ sub chown_ { sub mkswap { @_ == 1 or die "mkswap <device>\n"; - - require 'swap.pm'; + require swap; swap::enable($_[0], 0); } sub swapon { @_ == 1 or die "swapon <file>\n"; - - require 'swap.pm'; + require swap; swap::swapon($_[0]); } sub swapoff { @_ == 1 or die "swapoff <file>\n"; - require 'swap.pm'; + require swap; swap::swapoff($_[0]); } @@ -192,25 +208,29 @@ sub rights { $types[$_[0] >> 12 & 0xf] . $r; } +sub displaySize { + my $m = $_[0] >> 12; + $m == 4 || $m == 8 || $m == 10; +} + sub ls { my ($l , $h) = getopts(\@_, qw(lh)); $h and die "usage: ls [-l] <files...>\n"; @_ or @_ = '.'; @_ == 1 && -d $_[0] and @_ = glob_($_[0]); - foreach (sort @_) { + foreach (sort @_) { if ($l) { my @s = lstat or warn("can't stat file $_\n"), next; formline( "@<<<<<<<<< @<<<<<<< @<<<<<<< @>>>>>>>> @>>>>>>>>>>>>>>> @*\n", rights($s[2]), getpwuid $s[4] || $s[4], getgrgid $s[5] || $s[5], - $s[6] ? join ", ", unmakedev($s[6]) : $s[7], - scalar localtime $s[9], -l $_ ? "$_ -> " . readlink $_ : $_); + displaySize($s[2]) ? $s[7] : join(", ", unmakedev($s[6])), + scalar localtime $s[9], -l $_ ? "$_ -> " . readlink $_ : $_); print $^A; $^A = ''; } else { print "$_\n"; } } } - sub cp { my ($force) = getopts(\@_, qw(f)); @_ >= 2 or die "usage: cp [-f] <sources> <dest>\n(this cp does -Rl by default)\n"; @@ -233,12 +253,16 @@ sub cp { -d $dest or mkdir $dest, mode($src) or die "mkdir: can't create directory $dest: $!\n"; &$cp(glob_($src), $dest); } elsif (-l $src) { - symlink((readlink($src) || die "readlink failed: $!"), $dest) or die "symlink: can't create symlink $dest: $!\n"; + unless (symlink((readlink($src) || die "readlink failed: $!"), $dest)) { + my $msg = "symlink: can't create symlink $dest: $!\n"; + $force ? warn $msg : die $msg; + } } else { local (*F, *G); open F, $src or die "can't open $src for reading: $!\n"; open G, "> $dest" or $force or die "can't create $dest : $!\n"; - foreach (<F>) { print G $_ } + local $_; + while (<F>) { print G $_ } chmod mode($src), $dest; } } @@ -248,29 +272,37 @@ sub cp { sub ps { @_ and die "usage: ps\n"; - my ($pid, $cmd); + my ($pid, $rss, $cpu, $cmd); + my ($uptime) = split ' ', first(cat_("/proc/uptime")); + my $hertz = 100; - local (*STDOUT_TOP, *STDOUT); - format STDOUT_TOP = - PID CMD + require c; + my $page = c::getpagesize() / 1024; + + open PS, ">&STDOUT"; + format PS_TOP = + PID RSS %CPU CMD . - format = -@>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -$pid, $cmd + format PS = +@>>>> @>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +$pid, $rss, $cpu, $cmd . - foreach $pid (sort {$a <=> $b} grep { /\d+/ } all('/proc')) { - (($cmd) = cat_("/proc/$pid/cmdline")) =~ s/\0/ /g; - $cmd ||= (split ' ', (cat_("/proc/$pid/stat"))[0])[1]; - write STDOUT + my @l = split(' ', cat_("/proc/$pid/stat")); + $cpu = sprintf "%2.1f", max(0, min(99, ($l[13] + $l[14]) * 100 / $hertz / ($uptime - $l[21] / $hertz))); + $rss = (split ' ', cat_("/proc/$pid/stat"))[23] * $page; + (($cmd) = cat_("/proc/$pid/cmdline")) =~ s/\0/ /g; + $cmd ||= (split ' ', (cat_("/proc/$pid/stat"))[0])[1]; + write PS; } } sub dd { - my $u = "usage: dd [-h] [if=<file>] [of=<file>] [bs=<number>] [count=<number>]\n"; - (getopts(\@_, qw(h)))[0] and die $u; - my %h = (if => \*STDIN, of => \*STDOUT, bs => 512, count => undef); + my $u = "usage: dd [-h] [-p] [if=<file>] [of=<file>] [bs=<number>] [count=<number>]\n"; + my ($help, $percent) = getopts(\@_, qw(hp)); + die $u if $help; + my %h = (if => *STDIN, of => *STDOUT, bs => 512, count => undef); foreach (@_) { /(.*?)=(.*)/ && exists $h{$1} or die $u; $h{$1} = $2; @@ -279,29 +311,29 @@ sub dd { ref $h{if} eq 'GLOB' ? *IF = $h{if} : sysopen(IF, $h{if}, 0 ) || die "error: can't open file $h{if}\n"; ref $h{of} eq 'GLOB' ? *OF = $h{of} : sysopen(OF, $h{of}, 0x41) || die "error: can't open file $h{of}\n"; - $h{bs} =~ /(\d+)k$/ and $h{bs} = $1 * 1024; - $h{bs} =~ /(\d+)M$/ and $h{bs} = $1 * 1024 * 1024; - $h{bs} =~ /(\d+)G$/ and $h{bs} = $1 * 1024 * 1024 * 1024; + $h{bs} = removeXiBSuffix($h{bs}); for ($nb = 0; !$h{count} || $nb < $h{count}; $nb++) { + printf "\r%02.1d%%", 100 * $nb / $h{count} if $h{count} && $percent; $read = sysread(IF, $tmp, $h{bs}) or $h{count} ? die "error: can't read block $nb\n" : last; syswrite(OF, $tmp) or die "error: can't write block $nb\n"; $read < $h{bs} and $read = 1, last; } - print STDERR "$nb+$read records in\n"; - print STDERR "$nb+$read records out\n"; + print STDERR "\r$nb+$read records in\n"; + print STDERR "$nb+$read records out\n"; } sub head_tail { my ($h, $n) = getopts(\@_, qw(hn)); $h || @_ > 1 + bool($n) and die "usage: $0 [-h] [-n lines] [<file>]\n"; $n = $n ? shift : 10; - local *F; @_ ? open(F, $_[0]) || die "error: can't open file $_[0]\n" : (*F = \*STDIN); + local *F; @_ ? open(F, $_[0]) || die "error: can't open file $_[0]\n" : (*F = *STDIN); + local $_; if ($0 eq 'head') { - foreach (<F>) { $n-- or return; print } + while (<F>) { $n-- or return; print } } else { - @_ = (); foreach (<F>) { push @_, $_; @_ > $n and shift; } + @_ = (); while (<F>) { push @_, $_; @_ > $n and shift; } print @_; } } @@ -313,7 +345,7 @@ sub strings { $h and die "usage: strings [-o] [-n min-length] [<files>]\n"; $n = $n ? shift : 4; $/ = "\0"; @ARGV = @_; my $l = 0; while (<>) { - while (/[$printable_chars]\{$n,}/og) { + while (/[$printable_chars]{$n,}/og) { printf "%07d ", ($l + length $') if $o; print "$&\n" ; } @@ -324,20 +356,20 @@ sub strings { sub hexdump { my $i = 0; $/ = \16; @ARGV = @_; while (<>) { printf "%08lX ", $i; $i += 16; - print join(" ", map({ sprintf "%02X", $_ } unpack("C*", $_)), - ($_ =~ s/[^$printable_chars]/./og, $_)[1]), "\n"; + print join(" ", (map { sprintf "%02X", $_ } unpack("C*", $_)), + ($_ =~ s/[^$printable_chars]/./og, $_)[1]), "\n"; } } -sub more { +sub more { @ARGV = @_; - require 'devices.pm'; + require devices; my $tty = devices::make('tty'); - local *IN; open IN, "<$tty" or die "can't open $tty\n"; - my $n = 0; while (<>) { - ++$n == 25 and $n = <IN>, $n = 0; - print - } + local *IN; open IN, "<$tty" or die "can't open $tty\n"; + my $n = 0; while (<>) { + ++$n == 25 and $n = <IN>, $n = 0; + print + } } sub pack_ { @@ -351,7 +383,7 @@ sub pack_ { local *F; open F, $_ or die "can't read file $_: $!\n"; - while (read F, $t, $BUFFER_SIZE) { print $t; } + while (read F, $t, $BUFFER_SIZE) { print $t; } } } } @@ -370,7 +402,7 @@ sub unpack_ { print "$filename\n"; my $dir = dirname($filename); -d $dir or mkdir_('-p', $dir); - + local *G; open G, "> $filename" or die "can't write file $filename: $!\n"; while ($size) { @@ -379,3 +411,192 @@ sub unpack_ { } } } + +sub insmod { + my ($h) = getopts(\@_, qw(h)); + $h || @_ == 0 and die "usage: insmod <module> [options]\n"; + my $f = local $_ = shift; + + require run_program; + + #- try to install the module if it exist else extract it from archive. + #- needed for cardmgr. + unless (-r $f) { + $_ = $1 if m@.*/([^/]*)\.o@; + unless (-r ($f = "/lib/modules/$_.o")) { + $f = "/tmp/$_.o"; + my $cz = "/lib/modules" . (arch() eq 'sparc64' && "64") . ".cz"; -e $cz or $cz .= "2"; + if (-e $cz) { + run_program::run("packdrake -x $cz /tmp $_.o"); + } elsif (-e "/lib/modules.cpio.bz2") { + run_program::run("cd /tmp ; bzip2 -cd /lib/modules.cpio.bz2 | cpio -i $_.o"); + } else { + die "unable to find an archive for modules"; + } + } + } + -r $f or die "can't find module $_"; + run_program::run(["insmod_", "insmod"], "-f", $f, @_) or die("insmod $_ failed"); + unlink $f; +} + +sub modprobe { + my ($h) = getopts(\@_, qw(h)); + $h || @_ == 0 and die "usage: modprobe <module> [options]\n"; + my $name = shift; + require modules; + modules::load_deps("/modules/modules.dep"); + modules::load($name, '', @_); +} + +sub route { + @_ == 0 or die "usage: route\nsorry, no modification handled\n"; + my ($titles, @l) = cat_("/proc/net/route"); + my @titles = split ' ', $titles; + my %l; + open ROUTE, ">&STDOUT"; + format ROUTE_TOP = +Destination Gateway Mask Iface +. + format ROUTE = +@<<<<<<<<<<<< @<<<<<<<<<<<< @<<<<<<<<<<<< @<<<<<<< +$l{Destination}, $l{Gateway}, $l{Mask}, $l{Iface} +. + foreach (@l) { + /^\s*$/ and next; + @l{@titles} = split; + $_ = join ".", reverse map { hex } unpack "a2a2a2a2", $_ foreach @l{qw(Destination Gateway Mask)}; + $l{Destination} = 'default' if $l{Destination} eq "0.0.0.0"; + $l{Gateway} = '*' if $l{Gateway} eq "0.0.0.0"; + write ROUTE; + } +} + +sub df { + my ($h) = getopts(\@_, qw(h)); + my ($dev, $size, $free, $used, $use, $mntpoint); + open DF, ">&STDOUT"; + format DF_TOP = +Filesystem Size Used Avail Use Mounted on +. + format DF = +@<<<<<<<<<<<<<<<< @>>>>>>> @>>>>>>> @>>>>>>> @>>>>>% @<<<<<<<<<<<<<<<<<<<<<<<<< +$dev, $size, $used, $free, $use, $mntpoint +. + my %h; + foreach (cat_("/proc/mounts"), cat_("/etc/mtab")) { + ($dev, $mntpoint) = split; + $h{$dev} = $mntpoint; + } + foreach $dev (sort keys %h) { + ($size, $free) = common::df($mntpoint = $h{$dev}); + $size or next; + + $use = int (100 * ($size - $free) / $size); + $used = $size - $free; + if ($h) { + $used = int ($used / 1024) . "M"; + $size = int ($size / 1024) . "M"; + $free = int ($free / 1024) . "M"; + } + write DF if $size; + } +} + +sub kill { + my $signal = 15; + @_ or die "usage: kill [-<signal>] pids\n"; + $signal = (shift, $1)[1] if $_[0] =~ /^-(.*)/; + kill $signal, @_ or die "kill failed: $!\n"; +} + +sub lspci { + require detect_devices; + print join "\n", detect_devices::stringlist(), ''; +} +*lssbus = *lspci; + +sub dmesg { print cat_("/tmp/syslog"); } + +sub sort { + my ($n, $h) = getopts(\@_, qw(nh)); + $h and die "usage: sort [-n] [<file>]\n"; + local *F; @_ ? open(F, $_[0]) || die "error: can't open file $_[0]\n" : (*F = *STDIN); + if ($n) { + print sort { $a <=> $b } <F>; + } else { + print sort <F>; + } +} + +sub du { + my ($s, $h) = getopts(\@_, qw(sh)); + $h || !$s and die "usage: du -s [<directories>]\n"; + + my $f; $f = sub { + my ($e) = @_; + my $s = (lstat($e))[12]; + $s += sum map { &$f($_) } glob_("$e/*") if !-l $e && -d $e; + $s; + }; + print &$f($_) >> 1, "\t$_\n" foreach @_ ? @_ : glob_("*"); +} + +sub install_cpio($$;@) { + my ($dir, $name, @more) = @_; + + return "$dir/$name" if -e "$dir/$name"; + + my $cpio = "$dir.cpio.bz2"; + -e $cpio or return; + + eval { rm("-r", $dir) }; + mkdir $dir, 0755; + require run_program; + + my $more = join " ", map { $_ && "$_ $_/*" } @more; + run_program::run("cd $dir ; bzip2 -cd $cpio | cpio -id $name $name/* $more"); + + "$dir/$name"; +} + +sub bug { + my ($h) = getopts(\@_, "h"); + $h and die "usage: bug\nput file report.bug on fat formatted floppy\n"; + + require detect_devices; + mount devices::make(detect_devices::floppy()), "/fd0"; + + sub header { " +******************************************************************************** +* $_[0] +********************************************************************************"; + } + + local $\ = "\n"; + output "/fd0/report.bug", map { chomp; $_ } + header("lspci"), detect_devices::stringlist(), + header("pci_devices"), cat_("/proc/bus/pci/devices"), + header("fdisk"), `fdisk -l`, + header("scsi"), cat_("/proc/scsi/scsi"), + header("lsmod"), cat_("/proc/modules"), + header("cmdline"), cat_("/proc/cmdline"), + header("pcmcia: stab"), cat_("/var/run/stab"), + header("usb"), cat_("/proc/bus/usb/devices"), + header("partitions"), cat_("/proc/partitions"), + header("cpuinfo"), cat_("/proc/cpuinfo"), + header("syslog"), cat_("/tmp/syslog"), + header("ddcxinfos"), `ddcxinfos`, + header("ddebug.log"), cat_("/tmp/ddebug.log"), + header("install.log"), cat_("/mnt/root/install.log"), + ; + umount "/fd0"; + sync; +} + + +#-###################################################################################### +#- Wonderful perl :( +#-###################################################################################### +1; # + |