Summary: How to find out density of memory chips without openning machine

From: Ju-Lien Lim (julienlim@rocketmail.com)
Date: Sun Nov 23 1997 - 23:43:47 CST


Please see attachment for summary. Thanks again to everyone for their recommendations.

===
   Ju
   julienlim@rocketmail.com

__________________________________________________________________
Sent by Yahoo! Mail. Get your free e-mail at http://mail.yahoo.com

Summary: How to find out density of memory chips without openning machine

My thanks to the following people for their recommendations/suggestions:

Greg Coleman (G-tech Corp.) <greg@crusoe.crusoe.net>
Dan Penrod <dan@paradyne.com>
Matthew Stier <Matthew.Stier@tddny.fujitsu.com>
Anderson McCammont <and@ms.com>
Jim Harmon <jim@telecnnct.com>
Jim McVey <jmcvey@nhgri.nih.gov>
Brad Young <bbyoung@amoco.com>
Audrey Taylor <axt@gam.com>
Howard Modell <howie@warlok.ds.boeing.com>
Rick Reineman <rick@lunger.llnl.gov>
David S. Foster <foster@bial1.ucsd.edu>
Bismark Espinoza <bismark@alta.jpl.nasa.gov>
Sun System Admin <sysadm@its.brooklyn.cuny.edu>
Wes Pfarner - 5736 <wrpfarn@csua35.sandia.gov>
Deepak Wilson <Deepak_D_Wilson@notes.seagate.com>
Jeff Wasilko <jeffw@smoe.org>
Virginia Coffindaffer <Virginia.Coffindaffer@wang.com>
artur <artur@compugen.co.il>
Joel Lee <jlee@thomas.com>
Jens Fischer <jefi@su00330.kat.ina.de>
Matt Reynolds <reynolmd@aston.ac.uk>
Mick Morgan <sun-managers@open.gov.uk>

        Ju
        julienlim@rocketmail.com

--------------- Original Question ---------------

I was wondering if there was a way besides openning up the
machine to find out the density of the SIMMs in my Sun Sparc5
running Solaris 2.5.1. I know I can use the command "prtdiag"
but I cannot seem to find the command. Is there some other
way for me to find this information out *without openning up
the box*?

[And yes... I did try the find for prtdiag prtdiag [but
SUNWkvm is not installed]... Also, I should have mentioned
that I could not bring the system down since the computer is
physically at a different part of the country]

--------------- Summary ---------------
as root
/usr/platform/`uname -m`/sbin/prtdiag

-----
If your /var/adm/messages file is configured like most, there will be a
record of boot messages in that file, one of which is the result of the
memory diagnostics, which tells you the amount of memory installed, and
how much was tested.

----- cut here -----
#!/bin/perl
#
@config = `/usr/sbin/prtconf -pv`;
$i = 0;
foreach $line (@config)
{
        if ( $line =~ /\sname:\s+'memory'/ )
        {
                $j = $i - 2;
                if ($config[$j] =~ /\sreg:/)
                {
                        $gotit = $config[$j];
                        chop $gotit;
                        goto GotIt;
                }
        }
        $i = $i + 1;
}
printf "no 'memory' line??\n";
exit;

GotIt:
$gotit =~ s/\s+reg:\s+//;
$gotit =~ s/'//g;
@slots = split(/\./, $gotit);
$slot = 1;
$totmem = 0;
$machine = `/usr/bin/uname -m`;
chop $machine;
print "On this $machine machine ...\n";
if ("$machine" =~ /sun4u/)
{
        $val0 = 3;
        $valinc = 4;
        $cardtype = "DIMM";
}
else
{
        $val0 = 2;
        $valinc = 3;
        $cardtype = "SIMM";
}
$OneMeg = 0x00100000;
@banks = ("J201", "J303", "J202", "J301", "J305", "J203", "J302",
"J304");
for($val=$val0; $val < scalar(@slots); $val = $val + $valinc)
{
        $simm = $slots[$val];
        $simmsize = hex($simm) / $OneMeg;
        $totmem += $simmsize;
        if ("$cardtype" =~ /SIMM/)
        {
                printf "slot $slot has a " . $simmsize . "M $cardtype \n";
        }
        else
        {
                printf "bank $slot has 2 " . ($simmsize / 2) . "M SIMMs \n";
        }
        $slot = $slot + 1;
}
printf "total memory = " . $totmem . "M\n";

----- cut here -----

I've attached a script that works well to identify the size of the
SIMMs in your system. I've also attached 'whatami.sh'; I use it a lot.

#!/usr/bin/ksh
    /usr/sbin/prtconf -pv | grep -v translations > /tmp/prtconf.tmp
    type=`grep banner-name /tmp/prtconf.tmp |
      sed -e 's/.*'\''\(.*\)'\''/\1/'`

    ss20=false
    case "$type" in
        "Sun Ultra"*)
                groups=4
                ;;
        "SPARCstation 20"*)
                groups=3
                ss20=true
                ;;
        "SPARCstation LX"*)
                groups=3
                ;;
        "SPARCstation 5"*)
                groups=3
                ;;
        "") # IPX shows no banner name, don't no about other sun4c machines
                groups=3
                ;;
        default)
                echo "unknown machine type $banner-name for $var"
                ;;
    esac

# for debugging:
# echo "$type $groups"
# echo $reg

    banks=`awk '
      BEGIN { groups='$groups' }
      /reg:/ {reg=$2}
      /name:.*'\''memory'\''/ {
        nreg=split(reg,regar,".")
        for(i=groups;i<=nreg;i+=groups) print substr(regar[i],1,3)
      }' /tmp/prtconf.tmp | (echo 'ibase=16';cat) | bc`

    if [ $ss20 = true ]
    then
      echo $banks | awk '{for(i=1;i<=NF;i++) printf("%5s",$i)} END {print}' |
        sed -e 's/16 16/32/g'
    else
      echo $banks | awk '{for(i=1;i<=NF;i++) printf("%5s",$i)} END {print}'
    fi
#rm /tmp/prtconf.tmp
----------
X-Sun-Data-Type: shell-script
X-Sun-Data-Description: shell-script
X-Sun-Data-Name: whatami.sh
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 2298

#! /bin/sh
#
# @(#)whatami,v3.0 (Wayne.Thompson@Sun.COM) 07/21/92
#
MYNAME=`/bin/basename $0`
#
# Author:
# Wayne Thompson (w/contributions from Wolfgang Bachhuber)
#
# Synopsis:
usage=`/bin/sed -e "s/^ *//" << endusage
      usage: $MYNAME [-h]
endusage`
#
# Description:
# This script outputs various system/user specific bits of information
# which may be useful to System Administrators.
#
# Example Output:
#
# SunOS 5.x:
# DATE: Sun Jul 5 11:05:30 PDT 1992
# USER: root
# HOSTNAME: le0 = anywhere
# IP ADDRESS: le0 = 129.150.30.23
# MODEL: SUNW,Sun 4/75
# FRAME BUFFER(S): cgthree
# SunOS RELEASE: 5.0.1
# TYPE: homeless
# HOME FILESERVER: mirrors
# MEMORY: 32MB
# SWAP: 53.4MB total, 25.6MB used, 27.8MB available
# LOAD AVERAGE: 1.01, 0.58, 0.58
# DNS DOMAINNAME: EBay.Sun.COM
# NIS DOMAINNAME: mlpirws.EBay.Sun.COM
# SOFTWARE SERVER(S): speedo1
# DEFAULT PRINTER: pug
# ETHERNET ADDRESS: 8:0:20:e:47:6d
# HOSTID: 5540a99d
# DISK: c0t3d0 "SUN0207" (208MB unformatted)
# PARTITION: c0t3d0s0 mounted on / (11MB, 87% full)
# PARTITION: c0t3d0s6 mounted on /usr (127MB, 100% full)
# SWAP PARTITION: c0t3d0s1 (32MB)
# CDROM: c0t6d0
# FLOPPY: fd0 (3.5-inch floppy)
# TAPE: rst4 - Archive QIC-150 tape drive (150MB)
#
# SunOS 4.x:
# DATE: Sun Jul 5 11:04:37 PDT 1992
# USER: me
# HOSTNAME: le0 = mirrors
# IP ADDRESS: le0 = 129.150.30.117
# MODEL: Sun 4/60
# FRAME BUFFER(S): cgsix
# SunOS RELEASE: 4.1.1
# KERNEL ID: GENERIC.md
# TYPE: standalone
# MEMORY: 16MB
# SWAP: 47.9MB total, 21.4MB used, 26.5MB available
# LOAD AVERAGE: 0.50, 0.14, 0.04
# DNS DOMAINNAME: EBay.Sun.COM
# NIS DOMAINNAME: mlpirws.EBay.Sun.COM
# SOFTWARE SERVER(S): speedo1
# DEFAULT PRINTER: pug
# ETHERNET ADDRESS: 8:0:20:7:e9:d8
# HOSTID: 5100745b
# METAPARTITION: md0h mounted on /home (1487MB, 89% full)
# DISK: sd0 "SUN0207" (208MB unformatted)
# PARTITION: sd0a mounted on / (13MB, 75% full)
# PARTITION: sd0g mounted on /usr (112MB, 80% full)
# DISK: sd1 "SUN0327" (327MB unformatted)
# PARTITION: sd1c part of md0h
# DISK: sd2 "SUN0669" (669MB unformatted)
# PARTITION: sd2c part of md0h
# DISK: sd3 "SUN0669" (669MB unformatted)
# PARTITION: sd3c part of md0h
# FLOPPY: fd0 (3.5-inch floppy)
# TAPE: rst0 - Archive QIC-150 tape drive (150MB)
#
# Both HOSTNAME and IP ADDRESS contain the network interface (i.e. le0).
# Should a machine be configured for more than one interface, there would
# be multiple entries for HOSTNAME and IP ADDRESS.
#
# TYPE knows about the "official" definitions:
#
# disk-resource STANDALONE DATALESS DISKLESS
#
# / ufs ufs nfs
# swap spec spec nfs
# /usr ufs nfs nfs
# /home ufs nfs nfs
#
# And the following "unofficial" definitions:
#
# disk-resource HOMELESS SWAPFUL SERVER
#
# / ufs nfs (exports
# swap spec spec /export
# /usr ufs nfs /exec
# /home nfs nfs /*)
#
# If whatami can't determine the disk resource type of any of the
# four resources, type will be "unknown".
#
# TYPE: unknown (/=ufs, swap=unknown, /usr=ufs, /home=nfs)
#
# If all the resource types can be identified and they don't match
# any of the above definitions, then type will be "undefined".
#
# TYPE: undefined (/=ufs, swap=nfs, /usr=ufs, /home=ufs)
#
# SOFTWARE SERVER(S) is path-order sensitive. For example, my PATH:
# . /home/me/bin /home/me/.dist
# /usr/ucb /bin /usr/bin
# /usr/dist/exe /usr/dist/local/exe = hologram:/usr/dist
# /usr/sds/exe /usr/sds/local/exe = eb1sds1:/usr/sds
# ...
#
# NOTE:
# SOFTWARE SERVER(S) will only show up if they are referenced
# by the current path.
#
# Options:
# -h print command description.
#
# Environment:
# PRINTER default printer.
# HOME user's home directory.
#
# Files:
# /usr/include/mon/idprom.h : unknown
#
# SunOS 5.x: Root privilege is required to obtain some information.
# Don't know exactly where 5.x metastat will live or what
# its output will look like.
#

# >> BEGIN parse options >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #

while [ $# -gt 0 ]
do
    case $1 in
        -h) # help
            /bin/awk '
                /^$/ {
                    exit;
                }

                /^[# :]/ && NR > 1 {
                    print substr ($0, 3);
                }
            ' $0 |
            /bin/sed "
                /^$/{
                    N
                    /^\n$/D
                }
                s/\$MYNAME/$MYNAME/
            "
            exit 0
            ;;

        --) # end of options
            shift
            break
            ;;

        -*)
            echo >&2 "$MYNAME: error: $1: unknown option."
            echo >&2 "$usage"
            exit 1
            ;;

        *) # end of options
            break
            ;;
    esac
done

# << END parse options <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #

# >> BEGIN parse arguments >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #

case $# in
    0)
        ;;

    *)
        echo >&2 "$MYNAME: error: unexpected argument(s)."
        echo >&2 "$usage"
        exit 1
        ;;
esac

# << END parse arguments <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #

# >> BEGIN initialization >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #

## >> BEGIN function: arch >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

# Function:
# @(#)arch,v1.1 (Wayne.Thompson@Sun.COM) 05/14/92
#
# Description:
# This function emulates 4.x arch(1).
#
# Variables:
#
# Usage:
# arch
# arch -k
# arch archname
#
# Return:
# 0 success
# 1 non-success
#
# Dependencies:
# This function works under SunOs 3.x - 5.x.
#
# Bugs:
#

arch () {
    case $1 in
        '')
            /bin/arch $* 2>&- || /bin/expr `/bin/uname -m` : '\(sun[0-9]*\)'
            ;;

        -k)
            /bin/arch $* 2>&- || /bin/uname -m
            ;;

        *)
            if [ -x /bin/arch ]
            then
                /bin/arch $*
            else
                [ $* = `/bin/expr \`/bin/uname -m\` : '\(sun[0-9]*\)'` ]
            fi
            ;;
    esac
}

## << END function: arch <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

DF () {
    /bin/df $1 2>&- |
    /bin/awk '
        /^[Ff]ilesystem/ {
            getline;
            print "DF", "'"$1"'", $1;
        }
    '
}

## >> BEGIN function: hostname >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

# Function:
# @(#)hostname,v1.0 (Wayne.Thompson@Sun.COM) 02/15/92
#
# Description:
# This function emulates 4.x hostname(1) given no arguments.
#
# Variables:
#
# Usage:
# hostname
#
# Return:
#
# Dependencies:
# This funcion works under SunOs 3.x - 5.x.
#
# Bugs:
#

hostname () {
    /bin/hostname 2>&- || /bin/uname -n
}

## << END function: hostname <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN function: osr >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

# Function:
# @(#)osr,v1.0 (Wayne.Thompson@Sun.COM) 02/08/92
#
# Description:
# This function outputs the numeric portion of the current OS release.
#
# Variables:
#
# Usage:
# os=`osr`
#
# Return:
# 0 success
# 1 non-success
#
# Dependencies:
# This funcion works under SunOs 3.x - 5.x.
#
# Bugs:
#

osr () {
    /bin/expr `
        {
            /bin/uname -r ||
            /bin/cat /usr/sys/conf*/RELEASE
        } 2>&- ||
        /etc/dmesg |
        /bin/awk '
            BEGIN { status = 1 }
            /^SunOS Release/ { print $3; status = 0; exit }
            END { exit status }
        ' ||
        /bin/expr "\`
            /usr/ucb/strings -50 /vmunix |
            /bin/egrep '^SunOS Release'
        \`" : 'SunOS Release \([^ ]*\)'
    ` : '\([.0-9]*\)'
}

## << END function: osr <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN function: whoami >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

# Function:
# @(#)whoami,v1.0 (Wayne.Thompson@Sun.COM) 03/20/92
#
# Description:
# This function emulates 4.x whoami(1).
#
# Variables:
#
# Usage:
# whoami
#
# Return:
#
# Dependencies:
# This funcion works under SunOs 3.x - 5.x.
#
# Bugs:
#

whoami () {
    /usr/ucb/whoami 2>&- ||
    /bin/expr "`/bin/id`" : '[^(]*(\([^)]*\)'
}

## << END function: whoami <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

tab="`/bin/awk 'BEGIN {printf ("\""%c"\"", 9);exit;}'`"
os=`osr`
case $os in
    5*)
        SVR4=1
        ARP=/usr/sbin/arp
        PING=/usr/sbin/ping
        NETSTAT=/usr/bin/netstat
        IFCONFIG=/usr/sbin/ifconfig
        UPTIME=/usr/bin/uptime
        SHOWMOUNT=/usr/lib/fs/nfs/showmount
        sysdef=`/usr/sbin/sysdef 2>&-`
        devinfo=`/usr/sbin/sysdef -d 2>&-`
        prtconf=`/usr/sbin/prtconf -v 2>&-`
        ;;

    *)
        ARP=/etc/arp
        PING=/usr/etc/ping
        NETSTAT=/usr/ucb/netstat
        IFCONFIG=/etc/ifconfig
        UPTIME=/usr/ucb/uptime
        SHOWMOUNT=/usr/etc/showmount
        devinfo=`/usr/etc/devinfo 2>&-`
        ;;
esac
login=`whoami`
hostname=`hostname`
hostid=`
    /bin/hostid 2>&- || {
        /etc/sysdef -h 2>&- |
        /bin/awk '$1 != "*" {print $1}'
    }
`
archk=`arch -k`
domainname=`/bin/domainname`
namesvc=files
if rpcinfo -u $hostname ypbind 2>&- 1>&-
then
    nis=true
    namesvc=nis
fi
if /bin/nistest org_dir.$domainname 2>&-
then
    nisplus=true
    namesvc=nisplus
fi
offset=20 # info offset
fbs=
ETHER=unknown
KERNELID=unknown
MEM=unknown
RELEASE=unknown
SWAP=unknown
FB=unknown
eval `
    /etc/dmesg 2>&- |
    /bin/awk '
        /^Ethernet address =/ {
            ether = $NF;
            next;
        }

        /^mem =/ {
            mem = $3;
            next;
        }

        /\) #[1-9]/ {
            for (i = 1; i <= NF; i++)
                if ($i ~ /^\(/) break;
            release = $(i-1);
            kernelid = $i;
            next;
        }

        /^swap on/ {
            for (i = 1; i <= NF; i++)
                if ($i == "fstype") break;
            swap = $++i;
            next;
        }

        /^(((cg|bw|gp).*[0-9])|taac[0-9]) at/ {
            fbs[$1]++;
            if (fb) {
                if (fbs[$1] == 1)
                    fb = fb", "$1;
            }
            else {
                fb = $1;
            }
            next;
        }

        /^fd[0-9] at obio/ {
            floppy[++fdi] = $1;
            next;
        }

        /: 1 && $1 != "lo0" {
            print $1;
        }
    '
`

for iface in $ifaces
do
    ip=`
        $IFCONFIG $iface 2>&- |
        /bin/awk '
            $1 == "inet" {
                print $2;
            }
        '
    `

    [ $ip ] &&
    case $namesvc in
        nisplus)
            /usr/bin/nismatch addr=$ip hosts.org_dir.$domainname
            ;;

        nis)
            /bin/ypmatch $ip hosts.byaddr 2>&- ||
            /bin/grep -w $ip /etc/hosts
            ;;

        files)
            /bin/grep -w $ip /etc/hosts
            ;;
    esac |
    /bin/awk '
        {
            printf ("%'$offset's %s = %s\n"\
                , "HOSTNAME:" \
                , "'"$iface"'" \
                , $2 \
            );
        }

        END {
            printf ("%'$offset's %s = %s\n"\
                , "IP ADDRESS:" \
                , "'"$iface"'" \
                , "'"$ip"'" \
            );
        }
    '
done

## << END hostname(s) and IP addresse(s) <<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN model/cpu type >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ "$devinfo" ]
then
    echo "$devinfo" |
    /bin/awk '
        /^Node / {
            split($0, x, "'\''");
            if (split (x[2], y, "_") > 1) {
                model = y[1]"/"y[2];
            }
            else {
                model = y[1];
            }
            printf("%'"$offset"'s %s\n"\
                , "MODEL:" \
                , model \
            );
            next;
        }
       /^'"$tab"'Node '\''[A-Z][a-zA-Z]*,/ {
            split($0, x, "'\''");
            printf("%'"$offset"'s %s\n"\
                , "CPU:" \
                , x[2] \
            );
            next;
       }
    '
else
    idprom_h=/usr/include/mon/idprom.h
    [ -f /usr/include/mon/idprom.h ] || idprom_h=-

    echo "
        /* @(#)idprom.h 1.20 5/22/91 SMI */

        /*
         * Copyright (c) 1986,1990 by Sun Microsystems, Inc.
         */

        #ifndef _mon_idprom_h
        #define _mon_idprom_h

        #ifndef LOCORE
        /*
         * Structure declaration for ID prom in CPU and Ethernet boards
         */

        struct idprom {
                unsigned char id_format; /* format identifier */
                /* The following fields are valid only in format IDFORM_1. */
                unsigned char id_machine; /* machine type */
                unsigned char id_ether[6]; /* ethernet address */
                long id_date; /* date of manufacture */
                unsigned id_serial:24; /* serial number */
                unsigned char id_xsum; /* xor checksum */
                unsigned char id_undef[16]; /* undefined */
        };
        #endif LOCORE

        #define IDFORM_1 1 /* Format number for first ID proms */

        /*
         * The machine type field assignments are constrained such that the
         * IDM_ARCH_MASK bits define the CPU architecture and the remaining bits
         * identify the individual implementation of that architecture.
         */
        #define IDM_ARCH_MASK 0xf0 /* mask for architecture bits */
        #define IDM_ARCH_SUN2 0x00 /* arch value for Sun-2 */
        #define IDM_ARCH_SUN3 0x10 /* arch value for Sun-3 */
        #define IDM_ARCH_SUN4 0x20 /* arch value for Sun-4 */
        #define IDM_ARCH_SUN3X 0x40 /* arch value for Sun-3x */
        #define IDM_ARCH_SUN4C 0x50 /* arch value for Sun-4c */
        #define IDM_ARCH_SUN4M 0x60 /* arch value for Sun-4m */

        /*
         * All possible values of the id_machine field (so far):
         */
        #define IDM_SUN2_MULTI 1 /* Machine type for Multibus CPU brd */
        #define IDM_SUN2_VME 2 /* Machine type for VME CPU board */
        #define IDM_SUN3_CARRERA 0x11 /* Carrera CPU */
        #define IDM_SUN3_M25 0x12 /* M25 CPU */
        #define IDM_SUN3_SIRIUS 0x13 /* Sirius CPU */
        #define IDM_SUN3_PRISM 0x14 /* Prism CPU */
        #define IDM_SUN3_F 0x17 /* Sun3F CPU */
        #define IDM_SUN3_E 0x18 /* Sun3E CPU */
        #define IDM_SUN4 0x21 /* Sparc CPU */
        #define IDM_SUN4_COBRA 0x22 /* Cobra CPU */
        #define IDM_SUN4_STINGRAY 0x23 /* Stingray CPU */
        #define IDM_SUN4_SUNRAY 0x24 /* Sunray CPU */
        #define IDM_SUN3X_PEGASUS 0x41 /* Pegasus CPU */
        #define IDM_SUN3X_HYDRA 0x42 /* Hydra CPU */
        #define IDM_SUN4C 0x51 /* Campus CPU */
        #define IDM_SUN4C_60 0x51 /* Campus-1 CPU */
        #define IDM_SUN4C_40 0x52 /* Reserve some names */
        #define IDM_SUN4C_65 0x53 /* That we might do */
        #define IDM_SUN4C_20 0x54 /* It might be bigger */
        #define IDM_SUN4C_75 0x55 /* It might be smaller */
        #define IDM_SUN4C_30 0x56 /* It might be faster */
        #define IDM_SUN4C_50 0x57 /* It might be slower */
        #define IDM_SUN4C_70 0x58 /* It might cost more */
        #define IDM_SUN4C_80 0x59 /* It might cost less */
        #define IDM_SUN4C_10 0x5a /* It might sell well */
        #define IDM_SUN4C_45 0x5b /* And then it might not */
        #define IDM_SUN4C_05 0x5c /* It might be pink */
        #define IDM_SUN4C_85 0x5d /* It might be blue */
        #define IDM_SUN4C_32 0x5e /* I certainly don't know */
        #define IDM_SUN4C_HIKE 0x5f /* Do you? */

        #define IDM_SUN4M_690 0x61 /* SPARCsystem 600 series */

        #endif /*!_mon_idprom_h*/
    " |
    /bin/awk '
        BEGIN {
            mtype = sprintf ("0x%s", substr ("'"$hostid"'", 1, 2));
            cpu = "unknown";
        }

        $3 == mtype {
            if (split ($2, x, "_") > 2) {
                cpu = x[2]"/"x[3];
            }
            else {
                cpu = x[2];
            }
            exit;
        }

        END {
            printf ("%'"$offset"'s %s\n"\
                , "MODEL:" \
                , cpu \
            );
        }
    ' $idrpom_h
fi

## << END model/cpu type <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN frame buffer >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ "$devinfo" ]
then
    for fb in `
        echo "$devinfo" |
        /bin/awk '
            /Node '\''(bw|cg|gp|gt|taac|vx)(one|two|three|four|five|six|seven|eight|nine)/ {
                for (i = 1; i <= NF; i++) {
                    if ($i == "unit") unit = $(i+1);
                }
                split($0, x, "'\''");
                print x[2];
            }
        '
    `
    do
        fbs=${fbs:+"$fbs, "}$fb
    done
else
    cd /dev
    for fb in bw* cg* gp* gt* taac* vx*
    do
        [ -c $fb ] && { <$fb; } 2>&- && fbs=${fbs:+"$fbs, "}$fb
    done
fi

/bin/awk '
    BEGIN {
        printf ("%'"$offset"'s %s\n" \
            , "FRAME BUFFER(S):" \
            , "'"${fbs:-$FB}"'" \
        );
        exit;
    }
'

## << END frame buffer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN OS Release >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ $SVR4 ]
then
    /bin/awk '
        BEGIN {
            printf ("%'"$offset"'s %s\n" \
                , "SunOS RELEASE:" \
                , "'`/bin/uname -r`'" \
            );
            exit;
        }
    '
else
    strings -50 /vmunix 2>&- |
    /bin/awk '
        BEGIN {
            if ("'"$RELEASE"'" != "unknown") {
                printf ("%'"$offset"'s %s\n"\
                    , "SunOS RELEASE:" \
                    , "'"$RELEASE"'" \
                );
                printf ("%'"$offset"'s %s\n"\
                    , "KERNEL ID:" \
                    , "'"$KERNELID"'" \
                );
                exit;
            }
        }

        /\) #[1-9]/ {
            for (i = 1; i <= NF; i++) {
                if ($i ~ /^\(/) break;
            }
            printf ("%'"$offset"'s %s\n"\
                , "SunOS RELEASE:" \
                , $(i-1) \
            );
            printf ("%'"$offset"'s %s\n" \
                , "KERNEL ID:" \
                , substr ($i, 2, length ($i) - 2) \
            );
            exit;
        }
    '
fi

## << END OS Release <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN type >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

{
    DF /
    DF /usr
    DF `
        /bin/df $HOME |
        /bin/awk '
            BEGIN {
                home = "/home";
            }

            $NF ~ /^(\/tmp_mnt)*\/home/ {
                home = "'"$HOME"'";
            }

            END {
                print home;
            }
        '
    `
    $SHOWMOUNT -e 2>&-
} |
/bin/awk '
    BEGIN {
        osserver = homeserver = root = usr = home = "unknown";
        swap = "'$SWAP'";
        nfs = "nfs";
        spec = "spec";
        if ("'$SVR4'") {
            ufs = "ufs";
        }
        else {
            ufs = "4.2";
        }
        types["server"] = "server";
        types[ufs spec ufs ufs] = "standalone";
        types[ufs spec ufs nfs] = "homeless";
        types[ufs spec nfs nfs] = "dataless";
        types[nfs spec nfs nfs] = "swapful";
        types[nfs nfs nfs nfs] = "diskless";
    }

    /^DF \/ / {
        if (split ($3, x, ":") > 1 && x[1] != "'"$hostname"'") {
            root = "nfs";
        }
        else {
            root = ufs;
        }
        next;
    }

    /^DF \/usr/ {
        if (split ($3, x, ":") > 1 && x[1] != "'"$hostname"'") {
            osserver = x[1];
            usr = "nfs";
        }
        else {
            usr = ufs;
        }
        next;
    }

    /^DF .*\/home/ {
        if (split ($3, x, ":") > 1 && x[1] != "'"$hostname"'") {
            homeserver = x[1];
            home = "nfs";
        }
        else {
            home = ufs;
        }
        next;
    }

    /^\/export\/exec\// {
        type = server;
        exit;
    }

    END {
        printf ("%'"$offset"'s ", "TYPE:");
        if (root == "unknown" || \
            swap == "unknown" || \
            usr == "unknown" || \
            home == "unknown") {
            print "unknown (/="root", swap="swap", /usr="usr", /home="home")";
            if (osserver != "unknown") {
                printf ("%'"$offset"'s %s\n"\
                    , "OS FILESERVER:" \
                    , osserver \
                );
            }
            if (homeserver != "unknown") {
                printf ("%'"$offset"'s %s\n" \
                    , "HOME FILESERVER:" \
                    , homeserver \
                );
            }
            exit;
        }

        if (type == "server") {
            print type;
        }
        else if (type = types[root swap usr home]) {
            print type;
            if (type == types[ufs spec ufs ufs]) {
                exit;
            }
            else if (type == types[ufs spec ufs nfs]) {
                printf ("%'"$offset"'s %s\n"\
                    , "FILESERVER:" \
                    , homeserver \
                );
            }
            else if (osserver == homeserver) {
                printf ("%'"$offset"'s %s\n"\
                    , "FILESERVER:" \
                    , osserver \
                );
            }
            else {
                printf ("%'"$offset"'s %s\n"\
                    , "OS FILESERVER:" \
                    , osserver \
                );
                printf ("%'"$offset"'s %s\n"\
                    , "HOME FILESERVER:"\
                    , homeserver \
                );
            }
        }
    }
'

## << END type <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN memory >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ $SVR4 ]
then
    echo "$prtconf" |
    /bin/awk '
        /^Memory size:/ {
            printf ("%'"$offset"'s %sMB\n"\
                , "MEMORY:" \
                , $3 \
            );
            exit;
        }
    '
else
    /bin/awk '
        BEGIN {
            printf ("%'"$offset"'s %s\n"\
                , "MEMORY:" \
                , "'"$MEM"'" \
            );
            exit;
        }

    '
fi

## << END memory <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN swap >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

{
    /usr/sbin/swap -s 2>&- ||
    /etc/pstat -s 2>&-
} |
/bin/awk '
    {
        for (i = 1; i <= NF; i++) {
            if ($i ~ /used/) break;
            used = substr ($i, 1, length ($i) - 1);
            if (used < 10.24) {
                used_str = $i;
            }
            else {
                used_str = sprintf ("%.1fMB", used / 1024);
            }
        }

        for (i = 1; i <= NF; i++) {
            if ($i ~ /avail/) break;
            avail = substr ($i, 1, length ($i) - 1);
            if (avail < 10.24) {
                avail_str = $i;
            }
            else {
                avail_str = sprintf ("%.1fMB", avail / 1024);
            }
        }

        printf ("%'"$offset"'s %.1fMB total, %s used, %s available\n"\
            , "SWAP:" \
            , (used + avail) / 1024 \
            , used_str \
            , avail_str \
        );
    }
'

## << END swap <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN load average >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

$UPTIME 2>&- |
/bin/awk -F: '
    {
        printf ("%'"$offset"'s%s\n"\
            , "LOAD AVERAGE:" \
            , $NF \
        );
        exit;
    }
'

## << END load average <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN name service domainname(s) >>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

dns_domain=`
    {
        awk '/^domain/ {print $2; exit;}' /etc/resolv.conf 2>&- ||
        /bin/ypmatch $hostname. hosts 2>&- ||
        /bin/ypmatch $hostname\`
            /bin/expr \\\`/bin/domainname\\\` : '[^.]*\(.*\)'
        \` hosts 2>&-
    } |
    /bin/awk '
        {
            for (i = 2; i < split ($2, x, "."); i++) {
                domain = domain x[i] ".";
            }
            domain = domain x[i];
            print domain;
            exit;
        }
    '
`

if [ $dns_domain ]
then
    /bin/awk '
        BEGIN {
            printf ("%'"$offset"'s %s\n"\
                , "DNS DOMAINNAME:" \
                , "'"$dns_domain"'" \
            );
            exit;
        }
    '
fi

case $namesvc in
    files)
        ;;

    *)
        if [ $nisplus ]
        then
            /bin/awk '
                BEGIN {
                    printf ("%'"$offset"'s %s\n"\
                        , "NIS+ DOMAINNAME:" \
                        , "'"$domainname"'" \
                    );
                    exit;
                }
            '
        fi
        if [ $nis ]
        then
            /bin/awk '
                BEGIN {
                    printf ("%'"$offset"'s %s\n"\
                        , "NIS DOMAINNAME:" \
                        , "'"$domainname"'" \
                    );
                    exit;
                }
            '
        fi
        ;;
esac

## << END name service domainname(s) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN software server(s) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

{
    echo $PATH |
    /bin/tr : '\012'
    DF /usr/dist
    DF /usr/sds
    DF /usr/local
} |
/bin/awk '
    $1 == "DF" {
        for (i = 1; i <= t; i++) {
            if ($2 == type[i] && split ($3, x, ":") > 1) {
                softserv[type[i]] = x[1];
                s++;
                break;
            }
        }
        next;
    }

    /^\/usr\/(((dist|sds)\/exe)|local(\/bin)*)$/ {
        split ($0, x, "/");
        if (y["/usr/" x[3]]++ < 1) type[++t] = "/usr/" x[3];
    }

    END {
        if (s) {
            first = 1;
            printf ("%'"$offset"'s" \
                , "SOFTWARE SERVER(S):" \
            );
            for (i = 1; i <= t; i++) {
                if (softserv[type[i]]) {
                    if (first) {
                        printf (" %s", softserv[type[i]]);
                        first = 0;
                    }
                    else {
                        if (softserv[type[i]] != softserv[type[1]])
                            printf (", %s", softserv[type[i]]);
                    }
                }
            }
            printf ("\n");
        }
    }
' -

## << END software server(s) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN default printer >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

PRINTER=${PRINTER:-`
    /bin/awk '
        BEGIN {
            l = 0;
        }

        /\\$/ {
            line[l] = line[l] substr ($0, 1, length ($0) - 1);
            next;
        }

        {
            line[l] = line[l++] $0;
        }

        END {
            for (i = 0; i < l; i++) {
                if (line[i] ~ /^#/) continue;
                if (line[i] ~ /^lp[|:]|\|lp[|:]/) {
                    for (j = 1; j <= split (line[i], x, ":"); j++) {
                        if (j == 1) {
                            split (x[j], names, "|");
                            continue;
                        }
                        if (split (x[j], y, "=")) {
                            if (y[1] == "rp") {
                                print y[2];
                                exit;
                            }
                        }
                        for (k in names) {
                            if (names[k] \
                                ~ /^([0-9]|lp|lw|im|[Ii]magen|ps|[Pp]ost[Ss]cript)[0-9]*$/)
                                continue;
                            print names[k];
                            exit;
                        }
                        print names[1];
                        exit;
                    }
                    exit;
                }
            }
            print "none";
        }
    ' /etc/printcap 2>&- ||
    /bin/cat /etc/lp/default 2>&-
`}

/bin/awk '
    BEGIN {
        printf ("%'"$offset"'s %s\n" \
            , "DEFAULT PRINTER:" \
            , "'"${PRINTER:-none}"'" \
        );
        exit;
    }
'

## << END default printer <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN ethernet address >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

$PING -v $hostname 2>&- 1>&-
$ARP $hostname 2>&- |
/bin/awk '
    BEGIN {
        ether = "'"$ETHER"'";
    }

    / at / {
        ether = $4;
        exit;
    }

    END {
        printf ("%'"$offset"'s %s\n"\
            , "ETHERNET ADDRESS:" \
            , ether \
        );
    }
'

## << END ethernet address <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN hostid >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

/bin/awk '
    BEGIN {
        printf ("%'"$offset"'s %s\n"\
            , "HOSTID:" \
            , "'$hostid'" \
        );
        exit;
    }
'

## << END hostid <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN disks >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ $SVR4 ]
then
    mnttab=/etc/mnttab
else
    mnttab=/etc/mtab
fi

if [ -f /etc/format.dat ]
then
    format_dat=/etc/format.dat
else
    format_dat=/tmp/format.dat$$
    trap "rm -f $format_dat; exit" 0 1 2 3 15
    /bin/sed -e 's/^ //' << ' endsed' > $format_dat
        #
        #ident "@(#)format.dat 1.3 90/10/18 SMI"
        #
        # Copyright (c) 1991 by Sun Microsystems, Inc.
        #
        # Data file for the 'format' program. This file defines the known
        # disks, disk types, and partition maps.
        #

        #
        # This is the search path for 'format'. It contains all the disks that
        # will be searched for if no disk list is given on the command line.
        #
        search_path = xd0, xd1, xd2, xd3, xd4, xd5, xd6, xd7, xd8, xd9, xd10, xd11, \
                        xd12, xd13, xd14, xd15, xy[0-3], sd[0-7], sd8, sd9, sd10, \
                        sd11, sd12, sd13, sd14, sd15, id0[0-3][0-7]

        #
        # This is the list of supported disks for the Xylogics 450/451 controller.
        #
        disk_type = "Fujitsu-M2312K" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 587 : acyl = 2 : pcyl = 589 : nhead = 7 : nsect = 32 \
                : rpm = 3600 : bpt = 20480 : bps = 621 : drive_type = 1

        disk_type = "Fujitsu-M2284/M2322" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 821 : acyl = 2 : pcyl = 823 : nhead = 10 : nsect = 32 \
                : rpm = 3600 : bpt = 20480 : bps = 621 : drive_type = 2

        disk_type = "Fujitsu-M2351 Eagle" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 840 : acyl = 2 : pcyl = 842 : nhead = 20 : nsect = 46 \
                : rpm = 3961 : bpt = 28160 : bps = 595 : drive_type = 0

        disk_type = "Fujitsu-M2333" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 821 : acyl = 2 : pcyl = 823 : nhead = 10 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600 : drive_type = 3

        disk_type = "Fujitsu-M2361 Eagle" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 840 : acyl = 2 : pcyl = 842 : nhead = 20 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600 : drive_type = 3

        disk_type = "CDC EMD 9720" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 1147 : acyl = 2 : pcyl = 1217 : nhead = 10 : nsect = 48 \
                : rpm = 3600 : bpt = 30240 : bps = 613 : drive_type = 1

        disk_type = "Hitachi DK815-10" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 1735 : acyl = 2 : pcyl = 1737 : nhead = 15 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600 : drive_type = 1

        disk_type = "NEC D2363" \
                : ctlr = XY450 : fmt_time = 4 \
                : ncyl = 964 : acyl = 2 : pcyl = 1024 : nhead = 27 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600 : drive_type = 2

        #
        # This is the list of supported disks for the Xylogics 7053 controller.
        #
        disk_type = "Fujitsu-M2351 Eagle" \
                : ctlr = XD7053 \
                : ncyl = 840 : acyl = 2 : pcyl = 842 : nhead = 20 : nsect = 46 \
                : rpm = 3961 : bpt = 28160 : bps = 595

        disk_type = "Fujitsu-M2333" \
                : ctlr = XD7053 \
                : ncyl = 821 : acyl = 2 : pcyl = 823 : nhead = 10 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600

        disk_type = "Fujitsu-M2361 Eagle" \
                : ctlr = XD7053 \
                : ncyl = 840 : acyl = 2 : pcyl = 842 : nhead = 20 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600

        disk_type = "CDC EMD 9720" \
                : ctlr = XD7053 \
                : ncyl = 1147 : acyl = 2 : pcyl = 1217 : nhead = 10 : nsect = 48 \
                : rpm = 3600 : bpt = 30240 : bps = 613

        disk_type = "Hitachi DK815-10" \
                : ctlr = XD7053 \
                : ncyl = 1735 : acyl = 2 : pcyl = 1737 : nhead = 15 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600

        disk_type = "NEC D2363" \
                : ctlr = XD7053 \
                : ncyl = 964 : acyl = 2 : pcyl = 1024 : nhead = 27 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600

        disk_type = "Fujitsu-M2372K" \
                : ctlr = XD7053 \
                : ncyl = 743 : acyl = 2 : pcyl = 745 : nhead = 27 : nsect = 67 \
                : rpm = 3600 : bpt = 40960 : bps = 600

        disk_type = "CDC 9720-850" \
                : ctlr = XD7053 \
                : ncyl = 1358 : acyl = 2 : pcyl = 1360 : nhead = 15 : nsect = 66 \
                : rpm = 3600 : bpt = 41088 : bps = 610

        #
        # This is the list of supported disks for the Emulex MD21 controller.
        #
        disk_type = "Micropolis 1355" \
                : ctlr = MD21 \
                : ncyl = 1018 : acyl = 2 : pcyl = 1024 : nhead = 8 : nsect = 34 \
                : rpm = 3600 : bpt = 20832

        disk_type = "Toshiba MK 156F" \
                : ctlr = MD21 \
                : ncyl = 815 : acyl = 2 : pcyl = 830 : nhead = 10 : nsect = 34 \
                : rpm = 3600 : bpt = 20832

        disk_type = "Micropolis 1558" \
                : ctlr = MD21 \
                : ncyl = 1218 : acyl = 2 : pcyl = 1224 : nhead = 15 : nsect = 35 \
                : rpm = 3600 : bpt = 20833

        #
        # This is the list of supported disks for the ISP-80 IPI controller.
        #
        disk_type = "CDC IPI 9720" \
                : ctlr = "ISP-80" \
                : ncyl = 1631 : acyl = 1 : pcyl = 1633 : nhead = 15 : nsect = 82 \
                : rpm = 3600 : bpt = 50400

        disk_type = "CDC IPI 9722" \
                : ctlr = "ISP-80" \
                : ncyl = 1630 : acyl = 1 : pcyl = 1632 : nhead = 7 : nsect = 156 \
                : rpm = 3600 : bpt = 100800

        disk_type = "Seagate IPI ZBR Elite" \
                : ctlr = "ISP-80" \
                : ncyl = 1893 : acyl = 1 : pcyl = 1895 : nhead = 17 : nsect = 78 \
                : rpm = 5400 : bpt = 50400

        #
        # Following is a list of sample embedded SCSI disk configurations.
        #
        disk_type = "Quantum ProDrive 80S" \
                : ctlr = SCSI : fmt_time = 1 \
                : cache = 0x07 : trks_zone = 6 : atrks = 0 : asect = 1 \
                : ncyl = 832 : acyl = 2 : pcyl = 834 : nhead = 6 : nsect = 34 \
                : rpm = 3662 : bpt = 16896

        #disk_type = "CDC Wren VII 94601-12G" \
        # : ctlr = SCSI : fmt_time = 4 \
        # : cache = 0x11 : trks_zone = 15 : asect = 5 : atrks = 30 \
        # : ncyl = 1703 : acyl = 2 : pcyl = 1931 : nhead = 15 : nsect = 80 \
        # : rpm = 3597 : bpt = 41301

        #
        # An early CDC Wren IV, shipped with the 386i
        #
        #disk_type = "CDC Wren IV 94171-327" \
        # : ctlr = SCSI : fmt_time = 4 \
        # : cache = 0x11 : trks_zone = 9 : asect = 3 \
        # : ncyl = 1520 : acyl = 2 : pcyl = 1549 : nhead = 9 : nsect = 46 \
        # : rpm = 3600 : bpt = 20833

        #
        # This is the list of Sun supported disks for embedded SCSI.
        #
        disk_type = "Quantum ProDrive 105S" \
                : ctlr = SCSI : fmt_time = 1 \
                : cache = 0x07 : trks_zone = 6 : atrks = 0 : asect = 1 \
                : ncyl = 974 : acyl = 2 : pcyl = 1019 : nhead = 6 : nsect = 35 \
                : rpm = 3662 : bpt = 16896

        disk_type = "CDC Wren IV 94171-344" \
                : ctlr = SCSI : fmt_time = 4 \
                : cache = 0x11 : trks_zone = 9 : asect = 3 \
                : ncyl = 1545 : acyl = 2 : pcyl = 1549 : nhead = 9 : nsect = 46 \
                : rpm = 3600 : bpt = 20833

        disk_type = "SUN0104" \
                : ctlr = SCSI : fmt_time = 1 \
                : trks_zone = 6 : atrks = 0 : asect = 1 \
                : ncyl = 974 : acyl = 2 : pcyl = 1019 : nhead = 6 : nsect = 35 \
                : rpm = 3662 : bpt = 16896

        disk_type = "SUN0207" \
                : ctlr = SCSI \
                : trks_zone = 9 : atrks = 2: asect = 4 \
                : ncyl = 1254 : acyl = 2 : pcyl = 1272 : nhead = 9 : nsect = 36 \
                : rpm = 3600 : bpt = 18432

        disk_type = "SUN0327" \
                : ctlr = SCSI : fmt_time = 4 \
                : cache = 0x11 : trks_zone = 9 : asect = 3 \
                : ncyl = 1545 : acyl = 2 : pcyl = 1549 : nhead = 9 : nsect = 46 \
                : rpm = 3600 : bpt = 20833

        disk_type = "SUN0424" \
                : ctlr = SCSI : fmt_time = 4 \
                : trks_zone = 9 : asect = 2 \
                : ncyl = 1151 : acyl = 2 : pcyl = 2500 : nhead = 9 : nsect = 80 \
                : rpm = 4400 : bpt = 26000

        disk_type = "SUN0669" \
                : ctlr = SCSI : fmt_time = 4 \
                : trks_zone = 15 : asect = 5 : atrks = 30 \
                : ncyl = 1614 : acyl = 2 : pcyl = 1632 : nhead = 15 : nsect = 54 \
                : rpm = 3600 : bpt = 31410

        disk_type = "SUN1.0G" \
                : ctlr = SCSI : fmt_time = 4 \
                : trks_zone = 15 : asect = 5 : atrks = 30 \
                : ncyl = 1703 : acyl = 2 : pcyl = 1931 : nhead = 15 : nsect = 80 \
                : rpm = 3597 : bpt = 41301

        disk_type = "SUN1.3G" \
                : ctlr = SCSI : fmt_time = 4 \
                : trks_zone = 17 : asect = 6 : atrks = 17 \
                : ncyl = 1965 : acyl = 2 : pcyl = 3500 : nhead = 17 : nsect = 80 \
                : rpm = 5400 : bpt = 44823

        disk_type = "SUN2.1G" \
                : ctlr = SCSI : fmt_time = 4 \
                : ncyl = 2733 : acyl = 2 : pcyl = 3500 : nhead = 19 : nsect = 80 \
                : rpm = 5400 : bpt = 44823

        #
        # This is the list of partition tables for the Xylogics 450/451 controller.
        #
        partition = "Fujitsu-M2312K" \
                : disk = "Fujitsu-M2312K" : ctlr = XY450 \
                : 0 = 0, 15904 : 1 = 71, 33600 : 2 = 0, 131488 : 6 = 221, 81984

        partition = "Fujitsu-M2312K Old Type" \
                : disk = "Fujitsu-M2312K" : ctlr = XY450 \
                : 0 = 0, 15884 : 1 = 71, 33440 : 2 = 0, 131488 : 6 = 221, 81984

        partition = "Fujitsu-M2284/M2322" \
                : disk = "Fujitsu-M2284/M2322" : ctlr = XY450 \
                : 0 = 0, 16000 : 1 = 50, 33600 : 2 = 0, 262720 : 6 = 155, 213120

        partition = "Fujitsu-M2284/M2322 Old Type" \
                : disk = "Fujitsu-M2284/M2322" : ctlr = XY450 \
                : 0 = 0, 15884 : 1 = 50, 33440 : 2 = 0, 262720 : 6 = 155, 213120

        partition = "Fujitsu-M2351 Eagle" \
                : disk = "Fujitsu-M2351 Eagle" : ctlr = XY450 \
                : 0 = 0, 16560 : 1 = 18, 34040 : 2 = 0, 772800 : 6 = 55, 722200

        partition = "Fujitsu-M2351 Eagle Old Type" \
                : disk = "Fujitsu-M2351 Eagle" : ctlr = XY450 \
                : 0 = 0, 15884 : 1 = 18, 33440 : 2 = 0, 772800 : 6 = 55, 722200

        partition = "Fujitsu-M2333" \
                : disk = "Fujitsu-M2333" : ctlr = XY450 \
                : 0 = 0, 16080 : 1 = 24, 33500 : 2 = 0, 550070 : 6 = 74, 500490

        partition = "Fujitsu-M2361 Eagle" \
                : disk = "Fujitsu-M2361 Eagle" : ctlr = XY450 \
                : 0 = 0, 16080 : 1 = 12, 33500 : 2 = 0, 1125600 : 6 = 37, 1076020

        partition = "CDC EMD 9720" \
                : disk = "CDC EMD 9720" : ctlr = XY450 \
                : 0 = 0, 16320 : 1 = 34, 33600 : 2 = 0, 550560 : 6 = 104, 500640

        partition = "Hitachi DK815-10" \
                : disk = "Hitachi DK815-10" : ctlr = XY450 \
                : 0 = 0, 32160 : 1 = 32, 67335 : 2 = 0, 1743675 : 6 = 99, 1644180

        partition = "NEC D2363" \
                : disk = "NEC D2363" : ctlr = XY450 \
                : 0 = 0, 32562 : 1 = 18, 66933 : 2 = 0, 1743876 : 6 = 55, 1644381

        #
        # This is the list of partition tables for the Xylogics 7053 controller.
        #
        partition = "Fujitsu-M2351 Eagle" \
                : disk = "Fujitsu-M2351 Eagle" : ctlr = XD7053 \
                : 0 = 0, 16560 : 1 = 18, 34040 : 2 = 0, 772800 : 6 = 55, 722200

        partition = "Fujitsu-M2351 Eagle Old Type" \
                : disk = "Fujitsu-M2351 Eagle" : ctlr = XD7053 \
                : 0 = 0, 15884 : 1 = 18, 33440 : 2 = 0, 772800 : 6 = 55, 722200

        partition = "Fujitsu-M2333" \
                : disk = "Fujitsu-M2333" : ctlr = XD7053 \
                : 0 = 0, 16080 : 1 = 24, 33500 : 2 = 0, 550070 : 6 = 74, 500490

        partition = "Fujitsu-M2361 Eagle" \
                : disk = "Fujitsu-M2361 Eagle" : ctlr = XD7053 \
                : 0 = 0, 16080 : 1 = 12, 33500 : 2 = 0, 1125600 : 6 = 37, 1076020

        partition = "CDC EMD 9720" \
                : disk = "CDC EMD 9720" : ctlr = XD7053 \
                : 0 = 0, 16320 : 1 = 34, 33600 : 2 = 0, 550560 : 6 = 104, 500640

        partition = "Hitachi DK815-10" \
                : disk = "Hitachi DK815-10" : ctlr = XD7053 \
                : 0 = 0, 32160 : 1 = 32, 67335 : 2 = 0, 1743675 : 6 = 99, 1644180

        partition = "NEC D2363" \
                : disk = "NEC D2363" : ctlr = XD7053 \
                : 0 = 0, 32562 : 1 = 18, 66933 : 2 = 0, 1743876 : 6 = 55, 1644381

        partition = "Fujitsu-M2372K" \
                : disk = "Fujitsu-M2372K" : ctlr = XD7053 \
                : 0 = 0, 32562 : 1 = 18, 66933 : 2 = 0, 1344087: 6 = 55,1244592

        partition = "CDC 9720-850" \
                : disk = "CDC 9720-850" : ctlr = XD7053 \
                : 0 = 0, 32670 : 1 = 33, 67320: 2 = 0, 1344420: 6 = 101, 1244430

        #
        # This is the list of partition tables for the Emulex MD21 controller.
        #
        partition = "Micropolis 1355" \
                : disk = "Micropolis 1355" : ctlr = MD21 \
                : 0 = 0, 16048 : 1 = 59, 33456 : 2 = 0, 276896 : 6 = 182, 227392

        partition = "Micropolis 1355, large root" \
                : disk = "Micropolis 1355" : ctlr = MD21 \
                : 0 = 0, 31824 : 1 = 117, 59840 : 2 = 0, 276896 : 6 = 337, 185232

        partition = "Toshiba MK 156F" \
                : disk = "Toshiba MK 156F" : ctlr = MD21 \
                : 0 = 0, 15980 : 1 = 47, 33660 : 2 = 0, 277100 : 6 = 146, 227460

        partition = "Micropolis 1558, small root" \
                : disk = "Micropolis 1558" : ctlr = MD21 \
                : 0 = 0, 16275 : 1 = 31, 32550 : 2 = 0, 639450 : 6 = 93, 590625

        partition = "Micropolis 1558" \
                : disk = "Micropolis 1558" : ctlr = MD21 \
                : 0 = 0, 32025 : 1 = 61, 59850 : 2 = 0, 639450 : 6 = 175, 547575

        #
        # Following is a list of sample partition tables for embedded SCSI disks.
        #
        partition = "Quantum ProDrive 80S" \
                : disk = "Quantum ProDrive 80S" : ctlr = SCSI \
                : 0 = 0, 16384 : 1 = 64, 32512 : 2 = 0, 198144 : 6 = 191, 149248

        #partition = "CDC Wren VII 94601-12G" \
        # : disk = "CDC Wren VII 94601-12G" : ctlr = SCSI \
        # : 0 = 0, 32400 : 1 = 27, 64800 : 2 = 0, 2043600 : 6 = 81, 1946400

        #partition = "CDC Wren IV 94171-327" \
        # : disk = "CDC Wren IV 94171-327" : ctlr = SCSI \
        # : 0 = 0, 31878 : 1 = 77, 59616 : 2 = 0, 629280 : 6 = 221, 527786

        #
        # This is the list of partition tables for embedded SCSI controllers.
        #
        partition = "Quantum ProDrive 105S" \
                : disk = "Quantum ProDrive 105S" : ctlr = SCSI \
                : 0 = 0, 16170 : 1 = 77, 28140 : 2 = 0, 204540 : 6 = 211, 160230

        partition = "CDC Wren IV 94171-344, small root" \
                : disk = "CDC Wren IV 94171-344" : ctlr = SCSI \
                : 0 = 0, 16974 : 1 = 41, 33948 : 2 = 0, 639630 : 6 = 123, 588708

        partition = "CDC Wren IV 94171-344" \
                : disk = "CDC Wren IV 94171-344" : ctlr = SCSI \
                : 0 = 0, 31878 : 1 = 77, 59616 : 2 = 0, 639630 : 6 = 221, 548136

        partition = "SUN0104" \
                : disk = "SUN0104" : ctlr = SCSI \
                : 0 = 0, 16170 : 1 = 77, 28140 : 2 = 0, 204540 : 6 = 211, 160230

        partition = "SUN0207" \
                : disk = "SUN0207" : ctlr = SCSI \
                : 0 = 0, 16524 : 1 = 51, 65448 : 2 = 0, 406296 : 6 = 253, 324324

        partition = "SUN0327" \
                : disk = "SUN0327" : ctlr = SCSI \
                : 0 = 0, 31878 : 1 = 77, 59616 : 2 = 0, 639630 : 6 = 221, 548136

        partition = "SUN0424" \
                : disk = "SUN0424" : ctlr = SCSI \
                : 0 = 0, 33120 : 1 = 46, 65520 : 2 = 0, 828720 : 6 = 137, 730080

        partition = "SUN0669" \
                : disk = "SUN0669" : ctlr = SCSI \
                : 0 = 0, 32400 : 1 = 40, 64800 : 2 = 0, 1307340 : 6 = 120, 1210140

        partition = "SUN1.0G" \
                : disk = "SUN1.0G" : ctlr = SCSI \
                : 0 = 0, 32400 : 1 = 27, 64800 : 2 = 0, 2043600 : 6 = 81, 1946400

        partition = "SUN1.3G" \
                : disk = "SUN1.3G" : ctlr = SCSI \
                : 0 = 0, 34000 : 1 = 25, 133280 : 2 = 0, 2672400 : 6 = 123, 2505120

        partition = "SUN2.1G" \
                : disk = "SUN2.1G" : ctlr = SCSI \
                : 0 = 0, 62320 : 1 = 41, 197600 : 2 = 0, 4154160 : 6 = 171, 3894240

        #
        # This is the list of sample partition tables for IPI disks.
        #
        partition = "CDC IPI 9720" \
                : disk = "CDC IPI 9720" : ctlr = ISP-80 \
                : 0 = 0, 33210 : 1 = 27, 131610 : 2 = 0, 2006130 : 6 = 134, 196800 \
                : 7 = 294, 1644510

        partition = "CDC IPI 9722" \
                : disk = "CDC IPI 9722" : ctlr = ISP-80 \
                : 0 = 0, 33852 : 1 = 31, 132132 : 2 = 0, 1779960 : 6 = 152, 197652 \
                : 7 = 333, 1416324

        partition = "Seagate IPI ZBR Elite" \
                : disk = "Seagate IPI ZBR Elite" : ctlr = ISP-80 \
                : 0 = 0, 34476 : 1 = 26, 132600 : 2 = 0, 2510118 : 6 = 126, 663000 \
                : 7 = 626, 1680042
    endsed
fi

{
    /usr/etc/metastat
    if [ $SVR4 ]
    then
        /usr/sbin/prtvtoc /dev/rdsk/*s2 2>&-
        /usr/bin/df -F ufs -k 2>&-
    else
        for disk in `
            /bin/awk '
                BEGIN {
                    l = 0;
                }

                /\\\\$/ {
                    line[l] = line[l] substr($0, 1, length($0) - 1);
                    next;
                }

                {
                    line[l] = line[l++] $0;
                    if (line[l - 1] ~ /^[ ]*search_path/) {
                        exit;
                    }
                }

                END {
                    for (i = 0; i < l; i++) {
                        if (line[i] ~ /^[ ]*search_path/) {
                            split (line[i], a, "=");
                            for (j = 1; j <= split(a[2], b, ","); j++) {
                                if (n = split(c[split(b[j], c)], d, "[") == 1) {
                                    print d[1];
                                }
                                else {
                                    if (n == 2) {
                                        for (k = substr(d[2], 1, 1); k <= substr(d[2], 3, 1); k++) {
                                            print d[1] k;
                                        }
                                    }
                                    else {
                                        for (k = substr(d[2], 1, 1); k <= substr(d[2], 3, 1); k++) {
                                            for (l = substr(d[3], 1, 1); l <= substr(d[3], 3, 1); l++) {
                                                    print d[1] k l;
                                            }
                                        }
                                    }
                                }
                            }
                            exit;
                        }
                    }
                }
            ' $format_dat
        `
        do
            if [ -r /dev/${disk}c ]
            then
                { &-
            else
                /etc/dkinfo $disk 2>&-
            fi
        done
        /bin/df 2>&-
    fi
} 2>&- |
/bin/awk '
    BEGIN {
        l = 0;
    }

    FILENAME ~ /format.dat/ && /\\$/ {
        line[l] = line[l] substr($0, 1, length($0) - 1);
        next;
    }

    FILENAME ~ /format.dat/ {
        line[l] = line[l++] $0;
        next;
    }

    FILENAME == "'$mnttab'" && /^\/dev\/md\/dsk\// {
        metadisk++;
        metaparts[(disk = substr($1, 13, 2)) ++mnt[disk]] = \
            " mounted on "$2;
        sliceof[disk mnt[disk]] = disk;
        next;
    }

    FILENAME == "'$mnttab'" && /^\/dev\/dsk\// {
        parts[(disk = substr($1, 10, 6)) ++mnt[disk]] = \
            (s = substr($1, 16, 2))" mounted on "$2;
        sliceof[disk mnt[disk]] = disk s;
        next;
    }

    FILENAME == "'$mnttab'" && /^\/dev\/md/ {
        metadisk++;
        metaparts[(disk = substr($1, 6, length($1) - 6)) ++mnt[disk]] = \
            (s = substr($1, length($1), 1))" mounted on "$2;
        sliceof[disk mnt[disk]] = disk s;
        next;
    }

    FILENAME == "'$mnttab'" && /^\/dev\// {
        parts[(disk = substr($1, 6, length($1) - 6)) ++mnt[disk]] = \
            (s = substr($1, length($1), 1))" mounted on "$2;
        sliceof[disk mnt[disk]] = disk s;
        next;
    }

    /partition map/ {
        prtvtoc = 1; df = dkinfo = metastat 0;
        disk = substr(x[split($2, x, "/")], 1, 6);
        dk[++dki] = disk;
        ndisks++;
        next;
    }

    /^[Ff]ilesystem/ {
        df = 1; dkinfo = metastat = prtvtoc = 0;
        next;
    }

    prtvtoc == 1 {
        if ($NF == "bytes/sector") {
            bytes = $2;
            next;
        }
        if ($NF == "cylinders") {
            cylinders = $2;
            next;
        }
        if ($NF == "tracks/cylinder") {
            heads = $2;
            next;
        }
        if ($NF == "sectors/track") {
            sectors = $2;
            next;
        }
        if ($2 == "Partition") {
            disks[disk] = sprintf("%05d%05d%05d", cylinders, heads, sectors)
            size[disk] = int(cylinders * heads * sectors * bytes / 1000000);
            next;
        }
        if ($1 ~ /^[0-9]$/ && $3 == "01") {
            mnt[disk]++;
            parts[disk mnt[disk]] = $1;
            sliceof[disk mnt[disk]] = disk"s"$1;
            swap[sliceof[disk mnt[disk]]]++;
            size[sliceof[disk mnt[disk]]] = int($5 / (4 * bytes));
        }
        next;
    }

    df == 1 && /^\/dev\/md\/dsk\// {
        size[(slice = substr($1, 13, 2))] = int(($3 + $4) / 1024);
        cap[slice] = $5;
        next;
    }

    df == 1 && /\/dev\/dsk\// {
        size[(slice = substr($1, 10, 8))] = int(($3 + $4) / 1024);
        cap[slice] = $5;
        next;
    }

    df == 1 && /\/dev\// {
        size[(part = substr($1, 6, 8))] = int(($3 + $4) / 1024);
        cap[part] = $5;
        next;
    }

    /controller/ {
        dkinfo = 1; df = metastat = prtvtoc = 0;
        disk = substr($1, 1, index($1, ":") - 1);
        dk[++dki] = disk;
        getline;
        disks[disk] = sprintf("%05d%05d%05d", $1, $3, $5)
        size[disk] = int($1 * $3 * $5 * 512 / 1000000);
        ndisks++;
        next;
    }

    /^md[0-9][0-9]*:/ {
        metastat = 1; df = dkinfo = prtvtoc = 0;
        split($1, x, ":")
        mountp = substr(x[1], 2);
        next;
    }

    /^\/dev\/md[0-9][a-h]:/ {
        metastat = 1; df = dkinfo = prtvtoc = 0;
        mountp = substr(x[split($1, x, "/")], 1, 4);
        next;
    }

    metastat == 1 && /\/dev/ {
        disksuite[part = substr(x[split($1, x, "/")], 1, 9)] = mountp;
        mpart[++mmnt[disk = substr(part, 1, length(part) - 1)] disk] = part;
        next;
    }

    END {
        if (!ndisks) {
            exit;
        }
        for (i = 0; i < l; i++) {
            if (line[i] ~ /^disk_type/) {
                n = split(line[i], a);
                line[i] = "";
                for (j = 1; j <= n; j++) {
                    line[i] = line[i] a[j];
                }
                for (j = 1; j <= split(line[i], a, ":"); j++) {
                    split(a[j], b, "=");
                    if (b[1] == "disk_type") {
                        type = b[2];
                    }
                    else if (b[1] == "ncyl") {
                        ncyl = b[2];
                    }
                    else if (b[1] == "nhead") {
                        nhead = b[2];
                    }
                    else if (b[1] == "nsect") {
                        nsect = b[2];
                    }
                }
                table[sprintf("%05d%05d%05d", ncyl, nhead, nsect)] = type;
            }
        }
        if (metadisk) {
            for (part in metaparts) {
                disk = substr(part, 1, length(part) - 1);
                if (disk ~ /^d[1-9]/) {
                    slice = disk;
                }
                else {
                    slice = disk substr(metaparts[part], 1, 1);
                }
                printf ("%'"$offset"'s %s%s (%sMB, %s full)\n"\
                    , "METAPARTITION:" \
                    , disk \
                    , metaparts[part] \
                    , size[slice] \
                    , cap[slice] \
                );
            }
        }
        for (j = 1; j <= dki; j++) {
            if (size[dk[j]]) {
                printf ("%'"$offset"'s %s "\
                    , "DISK:" \
                    , dk[j] \
                );
                if (length(table[disks[dk[j]]])) {
                    print table[disks[dk[j]]], "(" size[dk[j]] "MB unformatted)";
                }
                else {
                    print "unknown", "(" size[dk[j]] "MB unformatted)";
                }
            }
            else {
                printf ("%'"$offset"'s %s\n"\
                    , "CDROM:" \
                    , dk[j] \
                );
                continue;
            }
            mounted = 0;
            if (mnt[dk[j]]) {
                mounted++;
                for (i = 1; i <= mnt[dk[j]]; i++) {
                    if (swap[sliceof[dk[j] i]]) {
                        printf ("%'"$offset"'s %s (%sMB)\n"\
                            , "SWAP PARTITION:" \
                            , sliceof[dk[j] i] \
                            , size[sliceof[dk[j] i]] \
                        );
                    }
                    else {
                        printf ("%'"$offset"'s %s%s (%sMB, %s full)\n"\
                            , "PARTITION:" \
                            , dk[j] \
                            , parts[dk[j] i] \
                            , size[sliceof[dk[j] i]] \
                            , cap[sliceof[dk[j] i]] \
                        );
                    }
                }
            }
            if (mmnt[dk[j]]) {
                mounted++;
                for (i = 1; i <= mmnt[dk[j]]; i++) {
                    printf ("%'"$offset"'s %s part of %s\n"\
                        , "PARTITION:" \
                        , mpart[i dk[j]] \
                        , disksuite[mpart[i dk[j]]] \
                    );
                }
            }
            if (!mounted) {
                printf ("%'"$offset"'s %s\n" \
                    , "PARTITION:" \
                    , "no mounted partitions" \
                );
            }
        }
    }
' $format_dat $mnttab -

## << END disks <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN floppy disks >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ "$devinfo" ]
then
    echo "$devinfo" |
    /bin/awk '
        /Node '\''fd'\''/ {
            for (i = 1; i <= NF; i++) {
                if ($i == "unit") unit = $(i+1);
            }
            split($0, x, "'\''");
            n = substr(unit, 2, 1);
            printf("%'"$offset"'s %s%d%s\n"\
                , "FLOPPY:" \
                , "fd" \
                , n \
                , " (3.5-inch floppy)" \
            );
        }
    '
else
    cd /dev
    for fd in fd[0-9]
    do
        { <${fd}c; } 2>&- && {
            eval "
                if [ \"$fd\" ]
                then
                    echo 3.5
                else
                    echo $fd
                fi
            "
        } |
        /bin/awk '
            /No such/ {
                next;
            }

            $1 == "3.5" {
                printf ("%'"$offset"'s %s - %s\n"\
                    , "FLOPPY:" \
                    , "'$fd'" \
                    , "3.5-inch floppy" \
                );
                next;
            }

            /^fd/ {
                if (length("'$archk'") == 4) {
                    printf ("%'"$offset"'s %s - %s\n"\
                        , "FLOPPY:" \
                        , $1 \
                        , "5.25-inch floppy" \
                    );
                }
                else {
                    printf ("%'"$offset"'s %s - %s\n"\
                        , "FLOPPY:" \
                        , $1 \
                        , "3.5-inch floppy" \
                    );
                }
            }
        '
    done
fi

## << END floppy disks <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN tapes >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

cd /dev
for tape in rst[0-7] rar[0-7] rxt[0-7] rtm[0-7]
do
    [ -c /dev/$tape ] &&
    /bin/mt -f /dev/$tape status 2>&1 |
    /bin/awk '
        BEGIN {
            tapetype = "unknown";
        }

        /No such device/ {
            tapetype = 0;
            exit;
        }

        /no tape loaded/ {
            tapetype = "unknown (no tape loaded)";
            exit;
        }

        /Device busy/ {
            tapetype = "unknown (busy)";
            exit;
        }

        /:$/ {
            tapetype = substr($0, 1, length($0) - 1);
        }
 
        /QIC-24/ {
            tapetype = tapetype " (60MB)";
            exit;
        }

        /QIC-150/ {
            tapetype = tapetype " (150MB)";
            exit;
        }

        END {
            if (tapetype) {
                printf ("%'$offset's %s - %s\n"\
                    , "TAPE:" \
                    , "'$tape'" \
                    , tapetype \
                );
            }
        }
    '
done

## << END tapes <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN cdroms >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

[ $SVR4 ] || {
    cd /dev
    for cd in `echo sr*`
    do
        case `{ <$cd; } 2>&1` in
            ''|*busy)
                echo $cd
                ;;
        esac
    done |
    /bin/awk '
        NR == 1 {
            cds = $0;
            next;
        }

        {
            cds = cds ", " $0
        }

        END {
            if (NR) {
                printf ("%'"$offset"'s %s\n"\
                    , "CDROM(S):" \
                    , cds \
                );
            }
        }
    '
}

## << END cdroms <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

# << END main <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #

----- cut here ----

To discover the memory arrangment within a given Sun without
actually opening the box, have a look at the following:

A routine called get_mem_conf will give you the results by slot,
bank or group, depending on the hardware. This may be enough, but
if not, try prtconf which will yield more info than anyone I know
can digest. But I think that I understand the memory part of it.

get_mem_conf is available from a sun-managers SUMMARY message from
omkumar@india.ti.com on Tue, 23 Sep 1997. You can get this script
from any of the sun-managers archive servers.

Remember that Ultra II's require memory in like groups of four, while
Ultra I's like it in like pairs and anything else goes one slot at
a time.

Several examples are attached from different real machines.

Use these codes for the prtconf decoding:

SIMM SS-XX Ultra 1 Ultra 2
Code Slot Bank Group
01000000 16MB
02000000 32MB
04000000 32MB 2 x 32MB
08000000 64MB 2 x 64MB
10000000 4 x 64MB
20000000 128MB 4 x 128MB

####

Ultra 1/170E with 448 MB comprised of six 64MB and two 32MB SIMMs
(cayman)

SIMMs must be installed in like pairs, first bank location unspecified.

# /usr/sbin/get_mem_conf
  128 128 128 64

bank 0 1 2 3

prtconf -pv [edited]

    Node 0xf004e7cc
        reg:
00000000.00000000.00000000.08000000.00000000.10000000.00000000.08000000.00000000
.20000000.00000000.08000000.00000000.30000000.00000000.04000000
        available:
00000000.33f3c000.00000000.00016000.00000000.30000000.00000000.03270000.00000000
.20000000.00000000.08000000.00000000.10000000.00000000.08000000.00000000.0000000
0.00000000.08000000
        name: 'memory'

decoded:
        reg:
00000000.00000000.00000000.08000000. Bank 0 128MB (2 x 64MB) rear
00000000.10000000.00000000.08000000. Bank 1 128MB (2 x 64MB)
00000000.20000000.00000000.08000000. Bank 2 128MB (2 x 64MB)
00000000.30000000.00000000.04000000 Bank 3 64MB (2 x 32MB) front

##########################################################################

Ultra 2/2200 with 256 MB (tortuga)

# /usr/sbin/get_mem_conf
  256

prtconf -pv [edited]

    Node 0xf004ee7c
        reg: 00000000.00000000.00000000.10000000
        available:
00000000.0ff3a000.00000000.00016000.00000000.0fc02000.00000000.00006000.00000000
.00000000.00000000.0f400000
        name: 'memory'

decoded:
        reg:
00000000.00000000.00000000.10000000 Group 0 256MB (4 x 64MB)

##########################################################################

Ultra 2/1300 with 256 MB (oahu)

SIMMS must be installed in groups of four, rearmost group first
(U0501,U0401,U0701,U0601)

# /usr/sbin/get_mem_conf
  128 128

prtconf -pv [edited]

    Node 0xf004eeb4
        reg:
00000000.00000000.00000000.08000000.00000000.20000000.00000000.08000000
        available:
00000000.27f3a000.00000000.00016000.00000000.27c02000.00000000.000de000.00000000
.20000000.00000000.07080000.00000000.00000000.00000000.08000000
        name: 'memory'

decoded:
        reg:
00000000.00000000.00000000.08000000. Group 0 128MB (4 x 32MB) rear
00000000.20000000.00000000.08000000 Group 1 128MB (4 x 32MB)
                                      Group 2 0MB
                                      Group 3 0MB front

##########################################################################

Ultra 2/2300 with 512 MB (nauru)

# /usr/sbin/get_mem_conf
  512

    Node 0xf004ee7c
        reg: 00000000.00000000.00000000.20000000
        available:
00000000.1ff3a000.00000000.00014000.00000000.00000000.00000000.1f0da000
        name: 'memory'

decoded:
        reg:
00000000.00000000.00000000.20000000 Group 0 512MB (4 x 128MB)

#############################################################################

SPARCstation 20 with 128 MB (bimini)

SIMMs may be installed singly, but slot J0201 must always be loaded.
Installation order: J0201, J0303, J0202, J0301, J0305, J0203, J0302,
J0304
SS-20s are strange, check the FE Manual or the SS-20 DSIMM/VSIMM manual.

# /usr/sbin/get_mem_conf
   32 32 32 32

# prtconf -pv [edited]

    Node 0xffd5d890
        reg:
00000000.00000000.01000000.00000000.02000000.01000000.00000000.08000000.01000000
.00000000.0a000000.01000000.00000000.0c000000.01000000.00000000.0e000000.0100000
0.00000000.18000000.01000000.00000000.1a000000.01000000
        available:
00000000.1af27000.00013000.00000000.1a000000.008c2000.00000000.18000000.01000000
.00000000.0e000000.01000000.00000000.0c000000.01000000.00000000.0a000000.0100000
0.00000000.08000000.01000000.00000000.02000000.01000000.00000000.00000000.010000
00
        name: 'memory'

decoded:
        reg:
00000000.00000000.01000000. slot 0 16MB
00000000.02000000.01000000. slot 1 16MB
00000000.08000000.01000000. slot 2 16MB
00000000.0a000000.01000000. slot 3 16MB
00000000.0c000000.01000000. slot 4 16MB
00000000.0e000000.01000000. slot 5 16MB
00000000.18000000.01000000. slot 6 16MB
00000000.1a000000.01000000 slot 7 16MB

##########################################################################

SPARCstation 20 with 96 MB (enewetok)

# /usr/sbin/get_mem_conf
   32 64

/usr/sbin/prtconf -pv
    Node 0xffd5d890
        reg:
00000000.00000000.01000000.00000000.02000000.01000000.00000000.14000000.04000000
        available:
00000000.17f27000.00013000.00000000.14000000.0397c000.00000000.02000000.01000000
.00000000.00000000.01000000
        name: 'memory'

decoded:
        reg:
00000000.00000000.01000000. slot 0 16MB
00000000.02000000.01000000. slot 1 16MB
00000000.14000000.04000000 slot 64MB

############################################################################

SPARCstation 5 with 64 MB (kauai)

# /usr/sbin/get_mem_conf
   32 32

/usr/sbin/prtconf -pv
    Node 0xffd2d124
        reg: 00000000.00000000.02000000.00000000.08000000.02000000
        available:
00000000.09f9f000.00013000.00000000.08000000.01ac1000.00000000.00000000.02000000
        name: 'memory'

decoded:
        reg:
00000000.00000000.02000000. slot 0 32MB
00000000.08000000.02000000 slot 1 32MB

-------
Use prtconf -vp. There will be a section under the title 'memory'
and you can use the info above that line to tell you what type of
simms are in which slots. It #is# a bit cryptic, but I've got a perl
script which will convert to english for you. I'll enclose it below.

Remember that in a Sparc 5, the simms will be installed in pairs, so
you will only get information about the total memory in each *pair* of
slots. EG the machine I'm working on has two 16M simms and two 4M
simms. The output of the program is:

Slot 1 has a 32 M SIMM
Slot 2 has a 8 M SIMM
Total memory = 40 M

------Cut here-----
#!/usr/local/bin/perl
#
@config = `/usr/sbin/prtconf -pv`;
$i = 0;
foreach $line (@config)
{
        if ( $line =~ /\sname:\s+'memory'/ )
        {
                $j = $i - 2;
                if ($config[$j] =~ /\sreg:/)
                {
                        $gotit = $config[$j];
                        chop $gotit;
                        goto GotIt;
                }
        }
        $i = $i + 1;
}
printf "no 'memory' line??\n";
exit;

GotIt:
$gotit =~ s/\s+reg:\s+//;
$gotit =~ s/'//g;
@slots = split(/\./, $gotit);
$slot = 1;
$totmem = 0;
$machine = `/usr/bin/uname -m`;
if ($machine =~ /sun4u/)
{
        $val0 = 3;
        $valinc = 4;
}
else
{
        $val0 = 2;
        $valinc = 3;
}
for($val=$val0; $val < scalar(@slots); $val = $val + $valinc)
{
        $simm = $slots[$val];
        $simmsize = "*** Unrecognised *** ";
        if ($simm eq "10000000")
        {
                $simmsize =256;
        }
        if ($simm eq "08000000")
        {
                $simmsize =128;
        }
        if ($simm eq "04000000")
        {
                $simmsize = 64;
        }
        if ($simm eq "02000000")
        {
                $simmsize = 32;
        }
        if ($simm eq "01000000")
        {
                $simmsize = 16;
        }
        if ($simm eq "00800000")
        {
                $simmsize = 8;
        }
        if ($simm eq "00400000")
        {
                $simmsize = 4;
        }
        $totmem += $simmsize;
        printf "Slot $slot has a " . $simmsize . " M SIMM \n";
        $slot = $slot + 1;
}
printf "Total memory = " . $totmem . " M\n";

------Cut here-----

Here's a script that provides the most consistent and correct results was as follows (courtesy of
fischjns@kat.ina.de):

#!/bin/sh
prtconf -pv | grep -v translations > /tmp/prtconf.tmp type=`grep banner-name /tmp/prtconf.tmp |
sed -e 's/.*'\''\(.*\)'\''/\1/'`

ss20=false
case "$type" in
"Sun Ultra"*)
groups=4
;;
"SPARCstation 20"*)
groups=3
ss20=true
;;
"SPARCstation LX"*)
groups=3
;;
"SPARCstation 5"*)
groups=3
;;
"") # IPX shows no banner name, don't no about other sun4c machines
groups=3
;;
default)
echo "unknown machine type $banner-name for $var" ;;
esac

# for debugging:
# echo "$type $groups"
# echo $reg

banks=`awk '
BEGIN { groups='$groups' }
/reg:/ {reg=$2}
/name:.*'\''memory'\''/ {
nreg=split(reg,regar,".")
for(i=groups;i<=nreg;i+=groups) print substr(regar[i],1,3)
}' /tmp/prtconf.tmp | (echo 'ibase=16';cat) | bc`

if [ $ss20 = true ]
then
echo $banks | awk '{for(i=1;i<=NF;i++) printf("%5s",$i)} END {print}' |
sed -e 's/16 16/32/g'
else
echo $banks | awk '{for(i=1;i<=NF;i++) printf("%5s",$i)} END {print}'
fi

Jens made the following follow up comments:-

I forgot to mention in my mail that the output of my script shows the
amount of memory in each bank, so you need to know how much SIMMs
belong to
each bank if you realy want to know the size of each single SIMM.

E.g. if the output is 64 64 on an Ultra 1 this means that there are two
banks with 64 MB, each of them consist of 2 SIMMs with 32 MB each as
the
SIMMs in an Ultra 1 are installed in pairs.

Basically when I ran the script on my system it reported 3x32MB sim
banks which basically means (2x16MB)x3 (Ultras take simms in pairs). This
meant given the 8 total simm slots I had two to play with or a further pair
(2x16=32,2x32=64,2x128=256).

-----

Have a look at the utility memconf on
http://www.rkdltd.demon.co.uk/memconf.html
- but remember that you will be downloading a binary
from a site that you should not necessarily trust.
Downside is it does not work on the Servers
(sun4d) and some E series.

E.g.

# memconf -f
hostA is a SUNW,Ultra-1 (sun4u), with 128 MB of RAM
 
U0701 [0x00000000 - 0x0FFFFFFF]: 32 MB
U0601 [0x00000000 - 0x0FFFFFFF]: 32 MB
U0702 [0x10000000 - 0x1FFFFFFF]: 32 MB
U0602 [0x10000000 - 0x1FFFFFFF]: 32 MB
U0703 [0x20000000 - 0x2FFFFFFF]: Empty
U0603 [0x20000000 - 0x2FFFFFFF]: Empty
U0704 [0x30000000 - 0x3FFFFFFF]: Empty
U0604 [0x30000000 - 0x3FFFFFFF]: Empty

-----
Here's one on doing it from the "ok" prompt:

  In PROM (ok mode):
Ok> setenv diag-switch? true
Ok> reset
  Now before Banner appears you will see memory map.
Just don't forget to return diag-switch to false.
Ok> setenv diag-switch false.



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:12:10 CDT