\underline{report 1}

#! /bin/sh

# Nick Urbanik <nicku@vtc.edu.hk> # report information about the computer, reading from proc file system # and Linux hard disk partition (if any) and storing the result in # a directory that may be on a floppy disk.

# Designed to work with tomsrtbt or from a hard disk.

# Here is my attempt to find out whether the root device is a hard disk  10

# or a RAM disk. # Now what devices are hard disks? # could be a label (if read fstab, but not output of mount) # could be [hs]d[a-z][1-9][0-9]∗ # could be md[0-9]+ # return 0 if root partition is a hard disk # return 1 otherwise mounted on hd() {

   for line in "`mount | grep '[ \t]/[ \t]'`"

do  20

mount point=‘echo $ℓine | awk '{print $3}'‘

      if [ "$mount_point" = "/" ];

then

         device="`echo $line | awk '{print $1}'`"

is hd=‘echo $device |

                awk '/^\/dev\/[hs]d[a-z][1-9][0-9]*$/ {print 0; next}
                    /^\/dev\/md[0-9]+/ {print 0; next}
                    {print 1}'‘

return $is hd

fi;  30

done return 1;

}

# A utility subroutine used by other subroutines # checks that the directory $INFODIR exists. ensure INFODIR exists() {

subroutine=$1

   if [ −z "$INFODIR" −o ! −d "$INFODIR" ]

then  40

echo $prog: $subroutine called without initialised \$INFODIR

exit 1 fi

}

# A utility subroutine used by other subroutines # checks that the directory $c exists. ensure hd mountpoint exists() { subroutine=$1

if [ −z "$c" −o ! −d "$c" ]  50

then echo $prog: $subroutine called without initialised mount point \$c exit 1

fi }

# reads the output of fdisk, and dmesg, # and copies the content of a number of files in the /proc file system. # Assume that $INFODIR exists

report generic info() {  60

ensure INFODIR exists "report_generic_info"

fdisk −l > $INFODIR/fdisk 2>&1 # print plenty of stuff from proc: for f in ‘ls −1 /proc|grep −v kcore|grep −v ksyms|grep −v kmsg|grep −v '[0-9].*'‘ do

if [ ! −d /proc/$f ]; then echo $f: cat /proc/$f

echo ' '  70

fi done > $INFODIR/proc for f in /proc/sys/kernel/∗ do

if [ ! −d $f ]; then echo $f: cat $f echo ' '

fi

done > $INFODIR/proc−kernel  80

dmesg > $INFODIR/dmesg }

# print the device names of all partitions that fdisk # reported as having the parition type Linux print linux partition devices() {

if [ −f $INFODIR/fdisk ]; then

grep '83 *Linux' $INFODIR/fdisk | awk '{print $1}' else

fdisk −l 2> /dev/null|grep '83 *Linux' | awk '{print $1}'  90

fi }

# print the name of the root partition device on standard output if find it. # Assume the root partition on the hard disk is not mounted # Assume $c exists and is a directory: guess root partition() {

ensure hd mountpoint exists "guess_root_partition"

ensure INFODIR exists  "guess_root_partition"

100

# Oh dear, this assumes non-raid. # problems detecting raid, journalling file systems # 1. tomsrtbt won’t handle raid # 2. How determine what raid devices exist?

for d in ‘print linux partition devices‘ do

mount $d $c

if [ −f $c/etc/fstab ]

then  110

echo $d umount $c return

fi

umount $c done

}

# takes one parameter, the partition device file.

# mount the device on $c  120

mount root partition() { device=$1 if mount | grep $device > /dev/null 2>&1 then

# false return 1

fi ensure hd mountpoint exists "mount_root_partition"

if mount $device $c  130

then # true return 0

else echo $prog: unable to mount $device on $c\; giving up exit 1

fi }

# if we have something mounted on $c, read plenty of Linux system configuration 140

# files from it. We could do the same for windows, but I don’t know # enough about the registry.

copy config from root partition() { if mount | grep $c > /dev/null 2>&1 then

: else

echo $prog: nothing mounted on $c\; giving up

exit  150

fi if $use floppy; then

if mount | grep $a > /dev/null 2>&1

then : else

echo $prog: no floppy mounted on $a\; giving up exit

fi

fi  160

ensure INFODIR exists "copy_config_from_root_partition"

for i in fstab lilo.conf conf.modules modules.conf \ sysconfig/network issue resolv.conf hosts profile bashrc \ inittab auto.conf

do

cp −p $c/etc/$i $INFODIR/$d > /dev/null 2>&1 done if [ −d $c/etc/rc.d ]

then  170

tar cf − $c/etc/rc.d 2> /dev/null | bzip2 −9 > $INFODIR/rc−d.tar.bz2 fi

if [ −d "$c/etc/sysconfig" ]

then

tar cf − $c/etc/sysconfig 2> /dev/null | bzip2 −9 > $INFODIR/sysconfig.tar.bz2 fi

if [ −f "$c/var/log/messages" ]

then # bzip2 -9c $c/var/log/messages > $INFODIR/messages.bz2

tail −30000 $c/var/log/messages | bzip2 −9 > $INFODIR/messages.bz2  180

fi df > $INFODIR/df mount > $INFODIR/mount

}

# This subroutine is called automatically whenever the program exits, # either because exit was called (signal zero), or an interrupt, hangup # or terminate signal were sent to this script.

clean up() {  190

echo cleaning up… rmdir $a > /dev/null 2>&1 if $use floppy then

umount $FD > /dev/null 2>&1 fi

   if [ "$c" = "/tmp/c" ]

then umount $c > /dev/null 2>&1

rmdir $c  200

fi }

# tomsrtbt doesn’t have a basename. # given a file name like “/this/directory/name/contains/a/file”, # will print “file” basen() {

dir=$1;

   echo $dir | awk 'BEGIN{FS="/"}{print $NF}'

}  210

# find the first part of the hostname without the domain name part. # for example, if hostname gives “nickpc.tycm.vtc.edu.hk”, will print # “nickpc” # hostname -s doesnt work on tomsrtbt hostname short() {

   hostname | awk '{ sub( "\\..*$", "" ) }{ printf $0 }'

}

# tomsrtbt doesn’t have tr, so can’t use:  220

# INFODIR=$a/‘date | tr ’ :’ ’-’‘ # take output from the date command (which looks like: # Thu Feb 15 11:55:49 HKT 2001 # and replace all spaces and colons by hyphens, so it looks like this: # Thu-Feb-15-11-55-49-HKT-2001 # Windows is not happy about the colons as a file name. date to dir name() {

   date | awk '{ gsub( "[ :]", "-" ); printf $0 }'

}

230

usage() {

cat <<EOF Usage: $prog [OPTIONS] Read information from /proc and other sources about the computer and write it into files in a directory. Will search for a standard Linux root partition and read configuration files from it if found. Options:

−f, −−floppy Put reports into a FAT floppy instead of /tmp/reports

−h, −−help  Show this help and exit  240

−o dir, −odir put output into dir instead of /tmp/reports −d, −−debug Show all commands as they are executed

EOF

exit $1 }

prog=‘basen $0‘ a=/tmp/reports

c=/tmp/c  250

INFODIR=$a/‘date to dir name‘−‘hostname short‘

use floppy=false while [ $# -ne 0 ] # loop over arguments do

case $1 in −−)

shift break

;;  260

−f |−−floppy)

use floppy=true ;;

−d|−−debug)

set −x ;;

−h|−−help)  270
usage 0 1>&2

;;

−o)

use floppy=false INFODIR="$2" shift

;;

−o∗)  280

use floppy=false

INFODIR=‘echo "$1" | sed 's/-o//'‘ ;;

∗)

echo unknown option $1

usage 1 1>&2 ;; esac

shift  290

done

mkdir $c mkdir $a > /dev/null 2>&1 if $use floppy; then

echo "Getting basic info about this computer..."

echo insert a formatted floppy with some disk space, any key to continue… read anykey FD=/dev/fd0

if mount −t vfat $FD $a  300

then

: else

echo $prog: cannot mount floppy on $a\; giving up exit 1

fi fi # cleanup on exit, hangup, interrupt, quit, termination trap clean up 0 1 2 3 15

mkdir $INFODIR  310

report generic info

if mounted on hd then

c=/ copy config from root partition

else device=‘guess root partition‘ echo your root partition seems to be $device.

mount root partition $device  320

copy config from root partition umount $device

fi $use floppy && umount $a rmdir $a > /dev/null 2>&1