ossp-pkg/platform/platform.sh
1.1
##
## OSSP platform - Platform Identification
## Copyright (c) 2003 The OSSP Project <http://www.ossp.org/>
## Copyright (c) 2003 Ralf S. Engelschall <rse@engelschall.com>
##
## This file is part of OSSP platform, a Unix platform identification
## program which can be found at http://www.ossp.org/pkg/tool/platform/.
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2.0 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this library; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
## USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
##
## platform.sh: the program (language: Bourne-Shell)
##
# program information
prog_run="${prog_run}"
prog_cmd="platform"
prog_name="OSSP platform"
prog_vers="0.1.0"
prog_date="06-Sep-2003"
## _________________________________________________________________________
##
## COMMAND LINE PARSING
## (partly derived from GNU shtool's sh.common)
## _________________________________________________________________________
##
# the command line specification
str_usage="[-F|--format FORMAT]"
str_usage="$str_usage [-S|--sep STRING]"
str_usage="$str_usage [-C|--conc STRING]"
str_usage="$str_usage [-L|--lower]"
str_usage="$str_usage [-U|--lower]"
str_usage="$str_usage [-T|--type TYPE]"
str_usage="$str_usage [-v|--verbose]"
str_usage="$str_usage [-c|--concise]"
str_usage="$str_usage [-n|--newline]"
str_usage="$str_usage [-d|--debug]"
str_usage="$str_usage [-V|--version]"
str_usage="$str_usage [-h|--help]"
arg_spec="0="
opt_spec="F:S:C:L.U.T:v.c.n.d.V.h."
opt_alias="F:format,S:sep,C:conc,L:lower,T:type,v:verbose,c:consise,n:newline,d:debug,V:version,h:help"
opt_F="Class: %sc (%ac)\\nProduct: %sp (%ap)\\nTechnology: %st (%at)"
opt_S=" "
opt_C="/"
opt_L=no
opt_U=no
opt_T=""
opt_v=no
opt_c=no
opt_n=no
opt_d=no
opt_V=no
opt_h=no
# commonly used ASCII values
ASC_TAB=" "
ASC_NL="
"
# parse argument specification string
eval `echo $arg_spec |\
sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
# parse option specification string
eval `echo $opt_spec |\
sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
# parse option alias string
eval `echo $opt_alias |\
tr 'x-' 'x_' | sed -e 's/\([a-zA-Z0-9]\):\([^,]*\),*/opt_ALIAS_\2=\1;/g'`
# interate over argument line
opt_PREV=''
while [ $# -gt 0 ]; do
# special option stops processing
if [ ".$1" = ".--" ]; then
shift
break
fi
# determine option and argument
opt_ARG_OK=no
if [ ".$opt_PREV" != . ]; then
# merge previous seen option with argument
opt_OPT="$opt_PREV"
opt_ARG="$1"
opt_ARG_OK=yes
opt_PREV=''
else
# split argument into option and argument
case "$1" in
--[a-zA-Z0-9]*=*)
eval `echo "x$1" |\
sed -e 's/^x--\([a-zA-Z0-9-]*\)=\(.*\)$/opt_OPT="\1";opt_ARG="\2"/'`
opt_STR=`echo $opt_OPT | tr 'x-' 'x_'`
eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
;;
--[a-zA-Z0-9]*)
opt_OPT=`echo "x$1" | cut -c4-`
opt_STR=`echo $opt_OPT | tr 'x-' 'x_'`
eval "opt_OPT=\${opt_ALIAS_${opt_STR}-${opt_OPT}}"
opt_ARG=''
;;
-[a-zA-Z0-9]*)
eval `echo "x$1" |\
sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
-e 's/";\(.*\)$/"; opt_ARG="\1"/'`
;;
-[a-zA-Z0-9])
opt_OPT=`echo "x$1" | cut -c3-`
opt_ARG=''
;;
*)
break
;;
esac
fi
# eat up option
shift
# determine whether option needs an argument
eval "opt_MODE=\$opt_MODE_${opt_OPT}"
if [ ".$opt_ARG" = . ] && [ ".$opt_ARG_OK" != .yes ]; then
if [ ".$opt_MODE" = ".:" ] || [ ".$opt_MODE" = ".+" ]; then
opt_PREV="$opt_OPT"
continue
fi
fi
# process option
case $opt_MODE in
'.' )
# boolean option
eval "opt_${opt_OPT}=yes"
;;
':' )
# option with argument (multiple occurances override)
eval "opt_${opt_OPT}=\"\$opt_ARG\""
;;
'+' )
# option with argument (multiple occurances append)
eval "opt_${opt_OPT}=\"\$opt_${opt_OPT}\${ASC_NL}\$opt_ARG\""
;;
* )
echo "${prog_cmd}:Error: unknown option: \`$opt_OPT'" 1>&2
echo "${prog_cmd}:Hint: run \`${prog_run} -h' or \`man ${prog_cmd}' for details" 1>&2
exit 1
;;
esac
done
if [ ".$opt_PREV" != . ]; then
echo "${prog_cmd}:Error: missing argument to option \`$opt_PREV'" 1>&2
echo "${prog_cmd}:Hint: run \`${prog_run} -h' or \`man ${prog_cmd}' for details" 1>&2
exit 1
fi
# process help option
if [ ".$opt_h" = .yes ]; then
echo "Usage: ${prog_run} ${str_usage}"
exit 0
fi
# process version option
if [ ".$opt_V" = .yes ]; then
echo "${prog_name} ${prog_vers} (${prog_date})"
exit 0
fi
# complain about incorrect number of arguments
case $arg_MODE in
'=' )
if [ $# -ne $arg_NUMS ]; then
echo "${prog_cmd}:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
echo "${prog_cmd}:Hint: run \`${prog_run} -h' or \`man ${prog_cmd}' for details" 1>&2
exit 1
fi
;;
'+' )
if [ $# -lt $arg_NUMS ]; then
echo "${prog_cmd}:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
echo "${prog_cmd}:Hint: run \`${prog_run} -h' or \`man ${prog_cmd}' for details" 1>&2
exit 1
fi
;;
esac
## _________________________________________________________________________
##
## UTILITY FUNCTIONS
## _________________________________________________________________________
##
# map string to lower case
util_lower () {
echo "$1" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'
}
# map string to upper case
util_upper () {
echo "$1" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
## _________________________________________________________________________
##
## ASSEMBLE INITIAL INFORMATION
## _________________________________________________________________________
##
UNAME_MACHINE=`(uname -m) 2>/dev/null` ||\
UNAME_MACHINE=`(uname -p) 2>/dev/null` ||\
UNAME_MACHINE='unknown'
UNAME_SYSTEM=`(uname -s) 2>/dev/null` ||\
UNAME_SYSTEM='unknown'
UNAME_RELEASE=`(uname -r) 2>/dev/null` ||\
UNAME_RELEASE=`(uname -v) 2>/dev/null` ||\
UNAME_RELEASE='unknown'
UNAME="${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}"
if [ ".$opt_d" = .yes ]; then
echo "uname => ${UNAME}" 1>&2
fi
AC=""; AP=""; AT=""
SC=""; SP=""; ST=""
## _________________________________________________________________________
##
## DISPATCH INTO PLATFORMS
## _________________________________________________________________________
##
case "${UNAME}" in
# FreeBSD
*:FreeBSD:* )
# determine architecture
AC="${UNAME_MACHINE}"
case "${AC}" in
i386 ) AC="iX86" ;;
esac
AP="${AC}"
AT=`(/sbin/sysctl -n hw.model) 2>&1`
case "${AT}" in
*"Pentium Pro"* | *"Cyrix 6x86MX"* | *"Pentium II"* | *"Pentium III"* | *"Pentium 4"* | *"Celeron"* ) AT="i686" ;;
*"Pentium"* ) AT="i586" ;; *"i486[SD]X"* | *"Cyrix 486"* | *"Cyrix [56]x86"* | *"Blue Lightning" | *"Cyrix 486S/DX" ) AT="i486" ;;
*"i386[SD]X"* | *"NexGen 586"* ) AT="i386" ;;
* ) AT="${AP}" ;;
esac
# determine system
r=`echo "${UNAME_RELEASE}" |\
sed -e 's;[()];;' -e 's/\(-.*\)$/[\1]/'`
ST="FreeBSD ${r}"
SP="${ST}"
case "${r}" in
1.* ) SC="4.3BSD" ;;
* ) SC="4.4BSD" ;;
esac
;;
# GNU/Linux
*:Linux:* )
# determine architecture
AT="${UNAME_MACHINE}"
AP="${AT}"
case "${AP}" in
i[3-6]86 ) AP='iX86' ;;
esac
AC="${AP}"
# determine system
v_kern=`echo "${UNAME_RELEASE}" |\
sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/'`
v_libc=`(strings /lib/libc.so.* | grep '^GLIBC_' | sed -e 's/^GLIBC_//' |\
sort -n | tail -1 | sed -e 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/') 2>&1`
ST="GNU/Linux ${v_libc}/${v_kern}"
for tagfile in dummy `cd /etc && echo *[_-]release *[_-]version 2>/dev/null`; do
test ! -f /etc/${tagfile} && continue
n=`echo ${tagfile} | sed -e 's/[_-]release$//' -e 's/[_-]version$//'`
v=`cat /etc/${tagfile} | grep '[0-9]' | head -1 |\
sed -e 's/^/#/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
-e 's/^#.*$//'`
case "`util_lower ${n}`" in
debian ) n="Debian[ GNU/Linux]" ;;
redhat ) n="RedHat[ Linux}" ;;
suse ) n="SuSE[ Linux]" ;;
mandrake ) n="Mandrake[ Linux}" ;;
gentoo ) n="Gentoo[ Linux]" ;;
* ) n="${n}[ GNU/Linux]" ;;
esac
SP="$n $v"
done
[ ".$SP" = . ] && SP="${ST}"
SC="LSB"
;;
# Sun Solaris
*:SunOS:* )
# determine architecture
AT="${UNAME_MACHINE}"
case "${AT}" in
i86pc ) AT="iX86" ;;
esac
AP="${AT}"
case "${AP}" in
sun4[cdm] ) AP="SPARC32" ;;
sun4u ) AP="SPARC64" ;;
sun4* ) AP="SPARC" ;;
esac
AC="${AP}"
case "${AC}" in
SPARC* ) AC="SPARC" ;;
esac
# determine system
ST="[Sun ]SunOS ${UNAME_RELEASE}"
v=`echo "${UNAME_RELEASE}" |\
sed -e 's;^4\.;1.;' \
-e 's;^5\.\([0-6]\).*;2.\1;' \
-e 's;^5\.\([0-9][0-9]*\).*;\1;'`
SP="[Sun ]Solaris $v"
case "${UNAME_RELEASE}" in
4.* ) SC="4.2BSD" ;;
5.* ) SC="SVR4" ;;
esac
;;
# TODO ...ADD YOUR NEW PLATFORM CHECK HERE... TODO
# *:XXX:* )
# ...
# ;;
# ...A STILL UNKNOWN PLATFORM...
* )
AT="${UNAME_MACHINE}"
AP="${AT}"
AC="${AP}"
ST="${UNAME_SYSTEM} ${UNAME_RELEASE}"
SP="${ST}"
SC="${SP}"
;;
esac
## _________________________________________________________________________
##
## PROVIDE RESULT OUTPUT
## _________________________________________________________________________
##
# provide fallback values
[ ".$AT" = . ] && AT="${AP:-${AC}}"
[ ".$AP" = . ] && AP="${AT:-${AC}}"
[ ".$AC" = . ] && AC="${AP:-${AT}}"
[ ".$ST" = . ] && ST="${SP:-${SC}}"
[ ".$SP" = . ] && SP="${ST:-${SC}}"
[ ".$SC" = . ] && SC="${SP:-${ST}}"
# support explicit enforced verbose/concise output
if [ ".$opt_v" = .yes ]; then
opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%[\1]/g'`
elif [ ".$opt_c" = .yes ]; then
opt_F=`echo ":$opt_F" | sed -e 's/^://' -e 's/%\([as][cpt]\)/%<\1>/g'`
fi
# provide verbose and concise variants
AC_V=""; AC_N=""; AC_C=""
AP_V=""; AP_N=""; AP_C=""
AT_V=""; AT_N=""; AT_C=""
SC_V=""; SC_N=""; SC_C=""
SP_V=""; SP_N=""; SP_C=""
ST_V=""; ST_N=""; ST_C=""
for var_lc in at ap ac st sp sc; do
case "$opt_F" in
*"%[${val_lc}]"* | *"%{${val_lc}}"* | *"%${val_lc}"* | *"%<${val_lc}>"* )
var_uc=`util_upper "$var_lc"`
eval "val=\"\$${var_uc}\""
val_V=""; val_N=""; val_C=""
case "$opt_F" in
*"%[${var_lc}]"* )
val_V=`echo ":$val" | \
sed -e 's/^://' \
-e 's;\[\([^]]*\)\];\1;g' \
-e 's;<\([^>]*\)>;\1;'`
eval "${var_uc}_V=\"\${val_V}\""
;;
esac
case "$opt_F" in
*"%{${var_lc}}"* | *"%${var_lc}"* )
val_N=`echo ":$val" | \
sed -e 's/^://' \
-e 's;\[\([^]]*\)\];;g' \
-e 's;<\([^>]*\)>;\1;'`
eval "${var_uc}_N=\"\${val_N}\""
;;
esac
case "$opt_F" in
*"%<${var_lc}>"* )
val_C=`echo ":$val" | \
sed -e 's/^://' \
-e 's;\[\([^]]*\)\];;g' \
-e 's;[^<]*<\([^>]*\)>;\1;'`
eval "${var_uc}_C=\"\${val_C}\""
;;
esac
;;
esac
done
# create output string
output=`echo ":$opt_F" |\
sed -e "s/^://" \
-e "s;%\[ac\];${AC_V};g" \
-e "s;%{ac};${AC_N};g" \
-e "s;%ac;${AC_N};g" \
-e "s;%<ac>;${AC_C};g" \
-e "s;%\[ap\];${AP_V};g" \
-e "s;%{ap};${AP_N};g" \
-e "s;%ap;${AP_N};g" \
-e "s;%<ap>;${AP_C};g" \
-e "s;%\[at\];${AT_V};g" \
-e "s;%{at};${AT_N};g" \
-e "s;%at;${AT_N};g" \
-e "s;%<at>;${AT_C};g" \
-e "s;%\[sc\];${SC_V};g" \
-e "s;%{sc};${SC_N};g" \
-e "s;%sc;${SC_N};g" \
-e "s;%<sc>;${SC_C};g" \
-e "s;%\[sp\];${SP_V};g" \
-e "s;%{sp};${SP_N};g" \
-e "s;%sp;${SP_N};g" \
-e "s;%<sp>;${SP_C};g" \
-e "s;%\[st\];${ST_V};g" \
-e "s;%{st};${ST_N};g" \
-e "s;%st;${ST_N};g" \
-e "s;%<st>;${ST_C};g" \
-e 's/\\\\n/^/g' |\
tr '^' '\012'`
# support lower/upper-case mapping
if [ ".$opt_L" = .yes ]; then
output=`util_lower "$output"`
elif [ ".$opt_U" = .yes ]; then
output=`util_upper "$output"`
fi
# support particular separator and concatenator strings
output=`echo ":$output" |
sed -e 's/^://' \
-e "s; ;${opt_S};g" \
-e "s;/;${opt_C};g"`
# display output string
if [ ".$opt_n" = .yes ]; then
echo . | awk '{ printf("%s", output); }' output="$output"
else
echo "$output"
fi