sys_info.sh revision 1.9 1 #! /bin/sh
2
3 # $NetBSD: sys_info.sh,v 1.9 2017/08/23 18:15:53 agc Exp $
4
5 # Copyright (c) 2016 Alistair Crooks <agc (at] NetBSD.org>
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
10 # are met:
11 # 1. Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #
28
29 SYS_INFO_VERSION=$( D="\$Date: 2017/08/23 18:15:53 $"; set -f;
30 IFS=" /"; set -- $D; printf %s "$2$3$4" )
31
32 PATH=$(sysctl -n user.cs_path)
33 export PATH
34
35 LIBRARY_PATH=${LD_LIBRARY_PATH:-/usr/lib:/usr/X11R7/lib}
36
37 # default libraries when no args are given (sorted...)
38 LIBS=
39 LIBS="${LIBS} libc"
40 LIBS="${LIBS} libcurses"
41 LIBS="${LIBS} libdrm"
42 LIBS="${LIBS} libm"
43 LIBS="${LIBS} libresolv"
44 LIBS="${LIBS} libsqlite"
45 LIBS="${LIBS} libssh"
46 LIBS="${LIBS} libstdc++"
47 LIBS="${LIBS} libterminfo"
48 LIBS="${LIBS} libutil"
49 LIBS="${LIBS} libX11"
50 LIBS="${LIBS} libXaw7"
51 LIBS="${LIBS} libXcb"
52 LIBS="${LIBS} libXfont"
53 LIBS="${LIBS} libXft"
54 LIBS="${LIBS} libXrandr"
55 LIBS="${LIBS} libXt"
56
57 # short script to look for an executable $2, and if found, to place
58 # path in $1
59 # taken from pkgsrc bootstrap
60 which_prog()
61 {
62 local IFS _var _name _d -
63 set -f
64
65 _var="$1"; _name="$2"
66
67 eval _d=\"\$$_var\"
68 if [ -n "$_d" ]; then
69 # Variable is already set (by the user, for example)
70 return 0
71 fi
72
73 IFS=:
74 for _d in $PATH ; do
75 if [ -f "$_d/$_name" ] && [ -x "$_d/$_name" ]; then
76 # Program found
77 eval $_var=\""$_d/$_name"\"
78 return 0
79 fi
80 done
81
82 return 1
83 }
84
85 savedIFS=unset
86 saveIFS() { savedIFS="${IFS-unset}"; IFS="$1"; }
87 restIFS() { test "${savedIFS}" = unset && unset IFS || IFS="${savedIFS}"; }
88
89 run() {
90 # must send to stderr, as run is used in $() sometimes.
91 $verbose && printf >&2 '%s\n' "${PS4:-...: }${1}"
92 eval "$1"
93 }
94
95 # print out the version for the given argument (or everything)
96
97 # case patterns are sorted by output order so
98 # sys_info
99 # and
100 # sys_info | sort -f
101 # generate identical output
102
103 getversion() {
104 case "$1" in
105 '')
106 # arriving here implies all==true, not possible otherwise
107 ;&
108 awk)
109 run "awk --version | awk '{ print \$1 \"-\" \$3 }'"
110 $all || return 0 ;&
111 [Bb][Ii][Nn][Dd]|named)
112 run "named -v | awk '{ gsub(\"-\", \"\", \$2); gsub(\"P\", \"pl\", \$2); print tolower(\$1) \"-\" \$2 }'"
113 $all || return 0 ;&
114 bozohttpd|httpd)
115 v=$(run "/usr/libexec/httpd -G" 2>/dev/null)
116 case "${v}" in
117 "")
118 run "strings -a /usr/libexec/httpd | awk -F/ '\$1 == \"bozohttpd\" && NF == 2 { print \$1 \"-\" \$2; exit }'"
119 ;;
120 *)
121 printf '%s\n' "bozohttpd-${v##*/}"
122 ;;
123 esac
124 $all || return 0 ;&
125 bzip2)
126 run "bzip2 --help 2>&1 | awk '{ sub(\",\", \"\", \$7); print \"bzip2-\" \$7; exit }'"
127 $all || return 0 ;&
128 calendar)
129 v=$(run "calendar -v" 2>/dev/null || true)
130 case "${v}" in
131 "") printf '%s\n' "calendar-20150701" ;;
132 *) printf '%s\n' "${v}" ;;
133 esac
134 $all || return 0 ;&
135 dhcpcd)
136 run "dhcpcd --version | sed -e 's/ /-/g' -e 1q"
137 $all || return 0 ;&
138 ftpd)
139 run "strings -a /usr/libexec/ftpd | awk '\$1 == \"NetBSD-ftpd\" { print \"ftpd-\" \$2 }'"
140 $all || return 0 ;&
141 g++|c++)
142 run "g++ --version | awk '{ print \$1 \"-\" \$4; exit }'"
143 $all || return 0 ;&
144 gcc|cc)
145 run "gcc --version | awk '{ print \$1 \"-\" \$4; exit }'"
146 $all || return 0 ;&
147 grep)
148 run "grep --version | awk '{ print \$1 \"-\" \$4 \$5; exit }'"
149 $all || return 0 ;&
150 gzip)
151 run "gzip --version 2>&1 | awk '{ print \$2 \"-\" \$3 }'"
152 $all || return 0 ;&
153 lib*)
154 for L in ${1:-$LIBS}; do
155 saveIFS :
156 for d in ${LIBRARY_PATH} nowhere; do
157 restIFS
158 if [ -e ${d}/$L.so ]; then
159 run "ls -al \"${d}/$L.so\" | sed -e 's/^.*-> //' -e 's;^.*/;;' -e 's/\\.so\\./-/'"
160 break
161 fi
162 done
163 restIFS
164 test "$d" = nowhere && test -n "$1" &&
165 printf 2>&1 '%s\n' "$0: library $1 not found"
166 done
167 $all || return 0 ;&
168 [Nn]et[Bb][Ss][Dd]|kernel)
169 run "uname -sr | awk '{ print \$1 \"-\" \$2 }'"
170 $all || return 0 ;&
171 netpgp)
172 run "netpgp -V | awk '{ sub(\"/.*\", \"\", \$3); print \"netpgp-\" \$3; exit }'"
173 $all || return 0 ;&
174 netpgpverify)
175 run "netpgpverify -v | awk '{ print \$1 \"-\" \$3 }'"
176 $all || return 0 ;&
177 ntp)
178 run "ntpq --version | awk '{ sub(\"-.\", \"\"); sub(\"p\", \"pl\", \$2); print \"ntp-\" \$2 }'"
179 $all || return 0 ;&
180 openssh|ssh)
181 run "ssh -V 2>&1 | awk '{ sub(\"_\", \"-\", \$1); print tolower(\$1) }'"
182 $all || return 0 ;&
183 opensshd|sshd)
184 run "sshd -V 2>&1 | awk '/OpenSSH/ { sub(\"_\", \"D-\", \$1); print tolower(\$1) }'"
185 $all || return 0 ;&
186 openssl)
187 run "openssl version 2>/dev/null | awk '{ print tolower(\$1) \"-\" \$2 }'"
188 $all || return 0 ;&
189 pkg_info|pkg_install)
190 if which_prog infopath pkg_info; then
191 run "printf 'pkg_install-%s\n' $(${infopath} -V)"
192 fi
193 $all || return 0 ;&
194 sh)
195 run "set -- \$NETBSD_SHELL; case \"\$1+\$2\" in *+BUILD*) ;; +) set -- ancient;; *) set -- \"\$1\";;esac; printf 'sh-%s\\n' \$1\${2:+-\${2#BUILD:}}"
196 $all || return 0 ;&
197 sqlite|sqlite3)
198 run "sqlite3 --version | awk '{ print \"sqlite3-\" \$1 }'"
199 $all || return 0 ;&
200 sys_info)
201 run "printf '%s\n' sys_info-${SYS_INFO_VERSION}"
202 $all || return 0 ;&
203 tcsh)
204 if which_prog tcshpath tcsh; then
205 run "${tcshpath} --version | awk '{ print \$1 \"-\" \$2 }'"
206 fi
207 $all || return 0 ;&
208 tzdata)
209 if [ -f /usr/share/zoneinfo/TZDATA_VERSION ]; then
210 run "cat /usr/share/zoneinfo/TZDATA_VERSION"
211 else
212 run "printf '%s\n' tzdata-too-old-to-matter"
213 fi
214 $all || return 0 ;&
215 unbound)
216 if which_prog unboundpath unbound-control; then
217 run "${unboundpath} -h | awk '/^Version/ { print \"unbound-\" \$2 }'"
218 else
219 $all || printf >&2 '%s\n' "unbound: not found"
220 fi
221 $all || return 0 ;&
222 [uU]ser[lL]and|release)
223 run "sed </etc/release -e 's/ /-/g' -e 's/^/userland-/' -e 1q"
224 $all || return 0 ;&
225 xz)
226 run "xz --version | awk '{ print \$1 \"-\" \$4; exit }'"
227 $all || return 0 ;&
228
229 '') # never matches
230 ;; # but terminates ;& sequence
231
232 *) printf >&2 '%s\n' "Unrecognised subsystem: $1"
233 ERRS=1
234 ;;
235 esac
236 }
237
238 verbose=false
239 # check if we have our only option
240 while getopts "L:P:v" a; do
241 case "$a" in
242 v) verbose=true;;
243 L) LIBRARY_PATH=${OPTARG};;
244 P) PATH=${OPTARG};;
245 \?) printf >&2 '%s\n' \
246 "Usage: $0 [-P path] [-L libdirs] [-v] [system...]"
247 exit 2
248 esac
249 done
250 shift $((OPTIND - 1))
251
252 if [ $# -eq 0 ]; then
253 set -- ''
254 all=true
255 else
256 # note this deletes any attempt to use '' as an arg.
257 set -- $( printf '%s\n' "$@" | sort -u )
258 all=false
259 fi
260
261 ERRS=0
262 while [ $# -gt 0 ]; do
263 getversion "$1"
264 shift
265 done
266 exit $ERRS
267