xref: /netbsd-src/usr.bin/sys_info/sys_info.sh (revision 10564be9b772f0a03aee85673d4876774d8f2d56)
1#! /bin/sh
2
3# $NetBSD: sys_info.sh,v 1.18 2020/07/14 01:01:05 reed Exp $
4
5# Copyright (c) 2016 Alistair Crooks <agc@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
29SYS_INFO_VERSION=20200714
30
31PATH=$(sysctl -n user.cs_path)
32export PATH
33
34LIBRARY_PATH=${LD_LIBRARY_PATH:-/usr/lib:/usr/X11R7/lib}
35
36# default libraries when no args are given (sorted...)
37LIBS=
38LIBS="${LIBS} libc"
39LIBS="${LIBS} libcurses"
40LIBS="${LIBS} libdrm"
41LIBS="${LIBS} libm"
42LIBS="${LIBS} libresolv"
43LIBS="${LIBS} libsqlite"
44LIBS="${LIBS} libssh"
45LIBS="${LIBS} libstdc++"
46LIBS="${LIBS} libterminfo"
47LIBS="${LIBS} libutil"
48LIBS="${LIBS} libX11"
49LIBS="${LIBS} libXaw7"
50LIBS="${LIBS} libXcb"
51LIBS="${LIBS} libXfont"
52LIBS="${LIBS} libXft"
53LIBS="${LIBS} libXrandr"
54LIBS="${LIBS} libXt"
55
56# short script to look for an executable $2, and if found, to place
57# path in $1
58# taken from pkgsrc bootstrap
59which_prog()
60{
61	local IFS _var _name _d -
62	set -f
63
64	_var="$1"; _name="$2"
65
66	eval _d=\"\$$_var\"
67	if [ -n "$_d" ]; then
68		# Variable is already set (by the user, for example)
69		return 0
70	fi
71
72	IFS=:
73	for _d in $PATH ; do
74		if [ -f "$_d/$_name" ] && [ -x "$_d/$_name" ]; then
75			# Program found
76			eval $_var=\""$_d/$_name"\"
77			return 0
78		fi
79	done
80
81	return 1
82}
83
84savedIFS=unset
85saveIFS() { savedIFS="${IFS-unset}"; IFS="$1"; }
86restIFS() { test "${savedIFS}" = unset && unset IFS || IFS="${savedIFS}"; }
87
88run() {
89	 # must send to stderr, as run is used in $() sometimes.
90	 $verbose && printf >&2 '%s\n' "${PS4:-...: }${1}"
91	 eval "$1"
92}
93
94# print out the version for the given argument (or everything)
95
96# case patterns are sorted by output order so
97#	sys_info
98# and
99#	sys_info | sort -f
100# generate identical output
101
102getversion() {
103	case "$1" in
104	'')
105		$all || return 0 ;&
106	awk)
107		run "awk --version | awk '{ print \$1 \"-\" \$3 }'"
108		$all || return 0 ;&
109	[Bb][Ii][Nn][Dd]|named)
110		run "named -v | awk '{ gsub(\"-\", \"\", \$2); gsub(\"P\", \"pl\", \$2); print tolower(\$1) \"-\" \$2 }'"
111		$all || return 0 ;&
112	bozohttpd|httpd)
113		v=$(run "${destdir}/usr/libexec/httpd -G")
114		case "${v}" in
115		"")
116			run  "strings -a ${destdir}/usr/libexec/httpd | awk -F/ '\$1 == \"bozohttpd\" && NF == 2 { print \$1 \"-\" \$2; exit }'"
117			;;
118		*)
119			printf '%s\n' "bozohttpd-${v##*/}"
120			;;
121		esac
122		$all || return 0 ;&
123	bzip2)
124		run  "bzip2 --help 2>&1 | awk '{ sub(\",\", \"\", \$7); print \"bzip2-\" \$7; exit }'"
125		$all || return 0 ;&
126	calendar)
127		v=$(run "calendar -v" || true)
128		case "${v}" in
129		"")	printf '%s\n' "calendar-20150701" ;;
130		*)	printf '%s\n' "${v}" ;;
131		esac
132		$all || return 0 ;&
133	dhcpcd)
134		run  "dhcpcd --version | sed -e 's/ /-/g' -e 1q"
135		$all || return 0 ;&
136	dtc)
137		run "dtc --version | sed 's/Version: DTC /dtc-/'"
138		$all || return 0 ;&
139	ftpd)
140		run "strings -a /usr/libexec/ftpd | awk '\$1 == \"NetBSD-ftpd\" { print \"ftpd-\" \$2 }'"
141		$all || return 0 ;&
142	g++|c++)
143		run "g++ --version | awk '{ print \$1 \"-\" \$4; exit }'"
144		$all || return 0 ;&
145	gcc|cc)
146		run "gcc --version | awk '{ print \$1 \"-\" \$4; exit }'"
147		$all || return 0 ;&
148	grep)
149		run "grep --version | awk '{ print \$1 \"-\" \$4 \$5; exit }'"
150		$all || return 0 ;&
151	gzip)
152		run "gzip --version 2>&1 | awk '{ print \$2 \"-\" \$3 }'"
153		$all || return 0 ;&
154	lib*)
155		for L in ${1:-$LIBS}; do
156			saveIFS :
157			for d in ${LIBRARY_PATH} nowhere; do
158				restIFS
159				if [ -e ${d}/$L.so ]; then
160					run "ls -al \"${d}/$L.so\" | sed -e 's/^.*-> //' -e 's;^.*/;;' -e 's/\\.so\\./-/'"
161					break
162				fi
163			done
164			restIFS
165			test "$d" = nowhere && test -n "$1" &&
166				printf 2>&1 '%s\n' "$0: library $1 not found"
167		done
168		$all || return 0 ;&
169	[Nn]et[Bb][Ss][Dd]|kernel)
170		run "uname -sr | awk '{ print \$1 \"-\" \$2 }'"
171		$all || return 0 ;&
172	netpgp)
173		run "netpgp -V | awk '{ sub(\"/.*\", \"\", \$3); print \"netpgp-\" \$3; exit }'"
174		$all || return 0 ;&
175	netpgpverify)
176		run "netpgpverify -v | awk '{ print \$1 \"-\" \$3 }'"
177		$all || return 0 ;&
178	ntp)
179		run "ntpq --version | awk '{ sub(\"-.\", \"\"); sub(\"p\", \"pl\", \$2); print \"ntp-\" \$2 }'"
180		$all || return 0 ;&
181	openssh|ssh)
182		run "ssh -V 2>&1 | awk '{ sub(\"_\", \"-\", \$1); print tolower(\$1) }'"
183		$all || return 0 ;&
184	opensshd|sshd)
185		run "sshd -V 2>&1 | awk '/OpenSSH/ { sub(\"_\", \"D-\", \$1); print tolower(\$1) }'"
186		$all || return 0 ;&
187	openssl)
188		run "openssl version 2>/dev/null | awk '{ print tolower(\$1) \"-\" \$2 }'"
189		$all || return 0 ;&
190	pcap)
191		if which_prog tcpdumppath tcpdump; then
192			run "${tcpdumppath} -h 2>&1 | awk '\$1 == \"libpcap\" { sub(\" version \", \"-\"); print }'"
193		fi
194		$all || return 0 ;&
195	pkg_info|pkg_install)
196		if which_prog infopath pkg_info; then
197			run "printf 'pkg_install-%s\n' \$(${infopath} -V)"
198		fi
199		$all || return 0 ;&
200	sh)
201		run "set -- \$NETBSD_SHELL; case \"\$1+\$2\" in *+BUILD*) ;; +) set -- ancient;; *) set -- \"\$1\";;esac; printf 'sh-%s\\n' \$1\${2:+-\${2#BUILD:}}"
202		$all || return 0 ;&
203	sqlite|sqlite3)
204		run "sqlite3 --version | awk '{ print \"sqlite3-\" \$1 }'"
205		$all || return 0 ;&
206	sys_info)
207		run "printf '%s\n' sys_info-${SYS_INFO_VERSION}"
208		$all || return 0 ;&
209	tcpdump)
210		if which_prog tcpdumppath tcpdump; then
211			run "${tcpdumppath} -h 2>&1 | awk '\$1 == \"tcpdump\" { sub(\" version \", \"-\"); print }'"
212		fi
213		$all || return 0 ;&
214	tcsh)
215		if which_prog tcshpath tcsh; then
216			run "${tcshpath} --version | awk '{ print \$1 \"-\" \$2 }'"
217		fi
218		$all || return 0 ;&
219	tzdata)
220		if [ -f ${destdir}/usr/share/zoneinfo/TZDATA_VERSION ]; then
221			run "cat ${destdir}/usr/share/zoneinfo/TZDATA_VERSION"
222		else
223			run "printf '%s\n' tzdata-too-old-to-matter"
224		fi
225		$all || return 0 ;&
226	unbound)
227		if which_prog unboundpath unbound-control; then
228			run "${unboundpath} -h | awk '/^Version/ { print \"unbound-\" \$2 }'"
229		else
230			$all || printf >&2 '%s\n' "unbound: not found"
231		fi
232		$all || return 0 ;&
233	[uU]ser[lL]and|release)
234		run "sed <${destdir}/etc/release -e 's/ /-/g' -e 's/^/userland-/' -e 1q"
235		$all || return 0 ;&
236	wpa_supplicant)
237		if which_prog wpapath wpa_supplicant; then
238			run "${wpapath} -v | awk 'NF == 2 { sub(\" v\", \"-\"); print }'"
239		fi
240		$all || return 0 ;&
241	xz)
242		run "xz --version | awk '{ print \$1 \"-\" \$4; exit }'"
243		$all || return 0 ;&
244	yacc)
245		run "yacc -V | sed -e 's| ||g'"
246		$all || return 0 ;&
247
248	'')			# never matches
249		;;		# but terminates ;& sequence
250
251	*)	printf >&2 '%s\n' "Unrecognised subsystem: $1"
252		ERRS=1
253		;;
254	esac
255}
256
257verbose=false
258destdir=""
259# check if we have our only option
260while getopts "L:P:d:v" a; do
261	case "$a" in
262	L)	LIBRARY_PATH=${OPTARG};;
263	P)	PATH=${OPTARG};;
264	d)	PATH=${OPTARG}/bin:${OPTARG}/sbin:${OPTARG}/usr/bin:${OPTARG}/usr/sbin
265		LIBRARY_PATH=${OPTARG}/usr/lib:${OPTARG}/usr.X11R7/lib
266		destdir=${OPTARG};;
267	v)	verbose=true;;
268	\?)	printf >&2 '%s\n' \
269		    "Usage: $0 [-v] [-d destdir] [-L libdirs] [-P path] [system...]"
270		exit 2
271	esac
272done
273shift $((OPTIND - 1))
274
275if [ $# -eq 0 ]; then
276	set -- ''
277	all=true
278else
279	all=false
280fi
281
282ERRS=0
283while [ $# -gt 0 ]; do
284	getversion "$1"
285	shift
286done
287exit $ERRS
288