#!/sbin/sh
#
#
#     debuginfo.sh
#
#     (c) Copyright 2002 Sun Microsystems, Inc.
#
#
PATH=/bin:/usr/bin:/usr/sbin:/usr/ucb:/etc:/usr/etc:$PATH
MYNAME=`basename $0`
#
# Synopsis:
usage=`sed -e "s/^ *//" << endusage
      usage: $MYNAME [-h]
endusage`
#
# Description:
#     This script outputs various system specific bits of information which
#     may be useful to System Administrators.
#
# Example Output:
#                    USER: me
#                HOSTNAME: le0 = anywhere
#              IP ADDRESS: le0 = 129.150.30.23
#                     CPU: SUN4C/75
#         FRAME BUFFER(S): cgthree0
#              OS RELEASE: 4.1.1
#               KERNEL ID: GENERIC_SMALL
#                  MEMORY: 16MB
#                    SWAP: 47.9MB total, 20.1MB used, 27.9MB available
#            LOAD AVERAGE: 0.43, 0.10, 0.03
#          DNS DOMAINNAME: EBay.Sun.COM
#          NIS DOMAINNAME: mlpirws.EBay.Sun.COM
#        ETHERNET ADDRESS: 8:0:20:e:47:6d
#                  HOSTID: 5540a99d
#
#     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.
#
#     SOFTWARE SERVER(S) is path order senstive. For example, my PATH:
#         . /home/me/bin /home/me/.dist
#         /usr/ucb /bin /usr/bin
#         /usr/sds/exe /usr/sds/local/exe       = eb1sds1:/usr/sds
#         /usr/dist/exe /usr/dist/local/exe     = rintintin:/usr/dist
#         ...
#
# Options:
#     -h        print command description.
#
# Environment:
#     PRINTER   default printer.
#     HOME      user's home directory.
#
# Files:
#     /usr/include/mon/idprom.h <i/o    idprom header file
#     /var/adm/messages*        <i/o    system messages
#     /etc/passwd               <i/o    system password file
#
# Diagnostics:
#     Exit Status:
#         0     normal termination
#         1     abnormal termination
#
#     Errors (stderr):
#         usage
#         "unable to contact portmapper on localhost."
#
#     Warnings (stderr):
#
#     Info (stdout):
#
# Dependencies:
#
# Caveats:
#
# Bugs:
#     Some information is derived from dmesg(8) and /var/adm/messages*.
#         Information which has been flushed will result in:
#             <DESCRIPTION>: unknown
#
# >> BEGIN parse options >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #

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

                /^[# ]/ && NR > 1 {
                    print substr ($0, 3);
                }
            ' $0 |
            sed -e "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 verify prerequisites >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #

ping localhost 5 1>&- 2>&- || {
    echo >&2 "$MYNAME: error: unable to contact portmapper on localhost."
    exit 1;
}

# << END verify prerequisites <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #

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

hostname=`hostname`
hostid=`hostid`
rpcinfo -u $hostname 100007 2>&- 1>&- && nis=1  # running nis?
offset=20                                       # info offset
fbs=
ETHER=unknown
KERNELID=unknown
MEM=unknown
RELEASE=unknown
FB=unknown
eval `
    dmesg |
    awk '
        /Ethernet address =/ {
            ether = $NF;
            next;
        }

	/avail mem/ {
	    next;
	}
	
        /mem =/ {
	    for (i = 1; i <= NF; i++)
		if ($i == "=") break;
            mem = $++i;
            next;
        }

        /SunOS Release/ {
            for (i = 1; i <= NF; i++)
                if ($i == "Release") break;
            release  = $++i; i+=2;
	    kernelid = $i;
            next;
        }

        /(((cg|bw|gp|ffb).*[0-9])|taac[0-9]) at/ {
	    for (i = 1; i <= NF; i++)
		if ($i ~ /^(((cg|bw|gp|ffb).*[0-9])|taac[0-9])/)
			break;
            fbs[$i]++;
            if (fb) {
                if (fbs[$i] == 1)
                    fb = fb", "$i;
            }
            else {
                fb = $i;
            }
            next;
        }
        
        END {
            if (ether)   printf ("ETHER=%s;", ether);
            if (mem)     printf ("MEM=%sMB;"			\
               , substr (mem, 1, length (mem) - 1) / 1024);
            if (release) printf ("RELEASE=%s;", release);
	    if (kernelid) printf ("KERNELID=%s;", kernelid);
            if (fb)      printf ("FB=\"%s\";", fb);
        }
    '
`
for file in /var/adm/messages*
do
    [ "$ETHER"    != unknown ] &&
    [ "$KERNELID" != unknown ] &&
    [ "$MEM"      != unknown ] &&
    [ "$RELEASE"  != unknown ] &&
    [ "$FB"       != unknown ] &&
        break
    eval `
        awk '
            BEGIN {
                if ("'"$FB"'" != "unknown") {
                    fb = "'"$FB"'";
                    for (i = i ;i <= split ("'"$FB"'", x, ","); i++)
                        if (x[i]) fbs[x[i]]++;
                }
            }

            /Ethernet address =/ {
                ether = $NF;
                next;
            }

	    /avail mem/ {
		next;
	    }

            /mem =/ {
		for (i = 1; i <= NF; i++)
		    if ($i == "=") break;
		mem = $++i;
                next;
            }

            /SunOS Release/ {
                for (i = 1; i <= NF; i++)
                    if ($i == "Release") break;
                release  = $++i; i++;
		kernelid = $++i;
                next;
            }

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

            END {
                if (ether && "'"$ETHER"'" == "unknown")
                    printf ("ETHER=%s;", ether);
                if (mem && "'"$MEM"'" == "unknown")
                    printf ("MEM=%sMB;"			\
                        , substr (mem, 1, length (mem) - 1) / 1024);
                if (release && "'"$RELEASE"'" == "unknown")
		    printf ("RELEASE=%s;", release);
		if (kernelid && "'"$KERNELID"'" == "unknown")
		    printf ("KERNELID=%s;", kernelid);
                if (swap && "'"$SWAP"'" == "unknown")
                    printf ("SWAP=%s;", swap);
                if (fb)
                    printf ("FB=\"%s\";", fb);
            }
        ' $file
    `
done
# << END initialization <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #

# >> BEGIN main >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #

## >> BEGIN login >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

awk '
    BEGIN {
        printf ("%'$offset's %s\n"      \
            , "USER:"                   \
            , "'"`whoami`"'"            \
        );
        exit;
    }
'

## << END login <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGIN hostname(s) and IP addresse(s) >>>>>>>>>>>>>>>>>>>>>>>> ##

for iface in `
    netstat -i |
    awk '
        NR > 1 && $1 != "lo0" && $1 != "Name" {
            print $1;
        }
    '
`
do
    ip=`
        ifconfig $iface |
        awk '
            $1 == "inet" {
                print $2;
            }
        '
    `

    if [ "$nis" ]
    then
        ypmatch $ip hosts.byaddr 2>&- || grep -w $ip /etc/hosts
    else
        grep -w $ip /etc/hosts
    fi |
    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) <<<<<<<<<<<<<<<<<<<<<<<<<< ##

## >> BEGUN arch >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

awk '
    BEGIN {
	printf ("%'$offset's %s\n"	\
		, "ARCH:"		\
		, "'"`uname -p`"'"	\
	);
	exit;
    }
'

## << END arch <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

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

#in=/usr/include/sys/cpu.h [ -f /usr/include/sys/cpu.h ] || in=-
#
#echo "
#    #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
#" |
#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"    \
#            , "CPU:"                    \
#            , cpu                       \
#        );
#    }
#' $in
#
### << END cpu type <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

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

cd /dev
for fb in bw* cg* gp* taac*
do
    [ -c $fb ] && { : > $fb; } 2>&- && fbs=${fbs:+"$fbs, "}$fb
done

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

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

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

strings /kernel/genunix |
awk '
    BEGIN {
        if ("'"$RELEASE"'" != "unknown") {
            printf ("%'"$offset"'s %s\n"\
                , "SunOS RELEASE:"      \
                , "'"$RELEASE"'"        \
            );
            printf ("%'"$offset"'s %s\n"\
                , "KERNEL ID:"          \
                , "'"$KERNELID"'"       \
            );
            exit;
        }
    }

    /Release/ {
        for (i = 1; i <= NF; i++) {
            if ($i == "Release") {
                release = $++i;
                continue;
            }
            if ($i ~ /^\(/) break;
        }
        printf ("%'"$offset"'s %s\n"    \
            , "OS RELEASE:"             \
            , release                   \
        );
	printf ("%'"$offset"'s %s\n"            \
	    , "KERNEL ID:"                      \
	    , substr ($i, 2, length ($i) - 2)   \
	);
        exit;
    }
'

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


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

awk '
    BEGIN {
        printf ("%'"$offset"'s %s\n"    \
            , "MEMORY:"                 \
            , "'"$MEM"'"                \
        );
        exit;
    }

'

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

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

swap -s |
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 |
awk -F: '
    {
        printf ("%'"$offset"'s%s\n"     \
            , "LOAD AVERAGE:"           \
            , $NF                       \
        );
        exit;
    }
'

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

## >> BEGIN NIS and DNS domainname >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

if [ "$nis" ]
then
    nis_domainname=`domainname`
#    dns_domainname=`
#        ypmatch $hostname. hosts |
#        awk '
#            {
#                for (i = 2; i < split ($2, x, "."); i++) {
#                    printf ("%s.", x[i]);
#                }
#                print x[i];
#                exit;
#            }
#        '
#    `
else
    nis_domainname="not running ypbind"
    dns_domainname="not configured for DNS"
fi

awk '
    BEGIN {
        printf ("%'"$offset"'s %s\n"    \
            , "DNS DOMAINNAME:"         \
            , "'"$dns_domainname"'"     \
        );
#        printf ("%'"$offset"'s %s\n"    \
#            , "NIS DOMAINNAME:"         \
#            , "'"$nis_domainname"'"     \
#        );
        exit;
    }
'

## << END NIS and DNS domainname <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ##

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

{
    echo $PATH |
    tr : '\012'
    df /usr/dist /usr/sds /usr/local 2>&1
} |
awk '
    $1 ~ /^(Filesystem|df:)$/ {
        next;
    }

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

    $1 ~/:/ {
        for (i = 1; i <= t; i++) {
            if ($NF == type[i] && split ($1, x, ":") > 1) {
                softserv[type[i]] = x[1];
                s++;
                break;
            }
        }
        next;
    }

    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 ethernet address >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ##

awk '
    BEGIN {
        printf ("%'"$offset"'s %s\n"    \
            , "ETHERNET ADDRESS:"       \
            , "'"$ETHER"'"              \
        );
        exit;
    }
'

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

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

hostid |
awk '
    {
        printf ("%'"$offset"'s %s\n"    \
            , "HOSTID:"                 \
            , $0                        \
        );
    }
'

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

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