diff options
author | apb <apb@pkgsrc.org> | 2012-10-31 14:41:55 +0000 |
---|---|---|
committer | apb <apb@pkgsrc.org> | 2012-10-31 14:41:55 +0000 |
commit | 880c31542f9cfe4d0d9742ae4d9120a51f109ee0 (patch) | |
tree | c9a973db269a5b79b9a93d08a46ea890e118eeb0 /pkgtools | |
parent | b1ceb4997fa77eb11c2b489d71330bba1e6fd871 (diff) | |
download | pkgsrc-880c31542f9cfe4d0d9742ae4d9120a51f109ee0.tar.gz |
Add the ability for libkver to override all four of ostype, osrelease,
machine, and machine_arch. Add a helper script to simplify use of
libkver. Set VERSION=0.7.
An earlier version of this change was reviewed by seb@NetBSD.org.
Diffstat (limited to 'pkgtools')
-rw-r--r-- | pkgtools/libkver/Makefile | 13 | ||||
-rw-r--r-- | pkgtools/libkver/PLIST | 5 | ||||
-rw-r--r-- | pkgtools/libkver/files/Makefile | 4 | ||||
-rw-r--r-- | pkgtools/libkver/files/kver/Makefile | 4 | ||||
-rw-r--r-- | pkgtools/libkver/files/kver/kver.8 | 145 | ||||
-rw-r--r-- | pkgtools/libkver/files/kver/kver.sh | 247 | ||||
-rw-r--r-- | pkgtools/libkver/files/lib/kver.3 | 142 | ||||
-rw-r--r-- | pkgtools/libkver/files/lib/kver.c | 188 |
8 files changed, 696 insertions, 52 deletions
diff --git a/pkgtools/libkver/Makefile b/pkgtools/libkver/Makefile index ed7095be0c7..931a6de61e0 100644 --- a/pkgtools/libkver/Makefile +++ b/pkgtools/libkver/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.31 2012/09/11 23:19:35 asau Exp $ +# $NetBSD: Makefile,v 1.32 2012/10/31 14:41:55 apb Exp $ DISTNAME= libkver-${VERSION} CATEGORIES= pkgtools @@ -18,7 +18,7 @@ CHECK_PERMS= no NO_PKGTOOLS_REQD_CHECK= yes USE_BSD_MAKEFILE= yes -VERSION= 0.6 +VERSION= 0.7 ONLY_FOR_PLATFORM= NetBSD-*-* @@ -34,7 +34,14 @@ FILES_SUBST+= HAS_SYSCTL=true FILES_SUBST+= HAS_SYSCTL=false .endif -INSTALLATION_DIRS+= lib man/man3 man/cat3 +SUBST_CLASSES+= paths +SUBST_FILES.paths= kver/kver.sh kver/kver.8 lib/kver.3 +SUBST_SED.paths+= -e 's,@PREFIX@,${PREFIX},g' +SUBST_SED.paths+= -e 's,@SH@,${SH},g' +SUBST_STAGE.paths= post-patch + +INSTALLATION_DIRS+= sbin ${PKGMANDIR}/man8 ${PKGMANDIR}/cat8 +INSTALLATION_DIRS+= lib ${PKGMANDIR}/man3 ${PKGMANDIR}/cat3 .if empty(LDD_SYSCTL:M*libc*) INSTALLATION_DIRS+= sbin .endif diff --git a/pkgtools/libkver/PLIST b/pkgtools/libkver/PLIST index 56ed050cf42..b49780a17a5 100644 --- a/pkgtools/libkver/PLIST +++ b/pkgtools/libkver/PLIST @@ -1,8 +1,11 @@ -@comment $NetBSD: PLIST,v 1.3 2008/04/12 22:43:09 jlam Exp $ +@comment $NetBSD: PLIST,v 1.4 2012/10/31 14:41:55 apb Exp $ lib/libkver.a lib/libkver.so lib/libkver.so.1 lib/libkver.so.1.0 man/cat3/kver.0 +man/cat8/kver.0 man/man3/kver.3 +man/man8/kver.8 +sbin/kver ${PLIST.sysctl}sbin/sysctl diff --git a/pkgtools/libkver/files/Makefile b/pkgtools/libkver/files/Makefile index 6fd0ea8fed4..f77513e5383 100644 --- a/pkgtools/libkver/files/Makefile +++ b/pkgtools/libkver/files/Makefile @@ -1,6 +1,6 @@ -# $NetBSD: Makefile,v 1.3 2003/12/13 17:45:59 seb Exp $ +# $NetBSD: Makefile,v 1.4 2012/10/31 14:41:55 apb Exp $ -SUBDIR= lib +SUBDIR= kver lib .ifndef(LDD_SYSCTL) LDD_SYSCTL!= ldd /sbin/sysctl 2>&1 diff --git a/pkgtools/libkver/files/kver/Makefile b/pkgtools/libkver/files/kver/Makefile new file mode 100644 index 00000000000..d3721e45591 --- /dev/null +++ b/pkgtools/libkver/files/kver/Makefile @@ -0,0 +1,4 @@ +MAN= kver.8 +SCRIPTS= kver.sh + +.include <bsd.prog.mk> diff --git a/pkgtools/libkver/files/kver/kver.8 b/pkgtools/libkver/files/kver/kver.8 new file mode 100644 index 00000000000..0fcfbe62f1e --- /dev/null +++ b/pkgtools/libkver/files/kver/kver.8 @@ -0,0 +1,145 @@ +.\" $NetBSD: kver.8,v 1.1 2012/10/31 14:41:55 apb Exp $ +.\" +.Dd October 31, 2012 +.Os +.Dt KVER 8 +.Sh NAME +.Nm kver +.Nd run a command with overriden system version +.Sh SYNOPSIS +.Nm +.Op Fl s Ar ostype +.Op Fl r Ar osrelease +.Op Fl m Ar machine +.Op Fl p Ar machine_arch +.Ar command +.Op Ar argument ... +.Sh DESCRIPTION +The +.Nm +utility +provides a simple wrapper around the +.Xr kver 3 +library. +It converts its options to environment variables understood by +.Xr kver 3 , +sets the +.Ev LD_PRELOAD +environment variable to ensure that the +.Xr kver 3 +library +.Pq Pa @PREFIX@/lib/libkver.so +is loaded, +and executes the specified +.Ar command +with the specified +.Ar argument Ns s . +.Pp +The following options are accepted: +.Bl -tag -offset indent +.It Fl s Ar ostype +The operating system type, e.g. +.Qq Nx . +Sets the +.Ev LIBKVER_OSTYPE +environment variable. +.It Fl r Ar osrelease +The operating system release, e.g. +.Qq "6.0_STABLE" . +Sets the +.Ev LIBKVER_OSRELEASE +environment variable. +.It Fl m Ar machine +The operating hardware platform, e.g. +.Dq "amd64" . +Sets the +.Ev LIBKVER_MACHINE +environment variable. +.It Fl p Ar machine_arch +The machine processor architecture, e.g. +.Dq "x86_64" . +Sets the +.Ev LIBKVER_MACHINE_ARCH +environment variable. +.El +.Pp +If the +.Fl m Ar machine +option is specified and the +.Fl p Ar machine_arch +option is not specified, then +.Nm +checks that +.Ar machine +is valid, and attempts to set an appropriate value for +.Va machine_arch ; +for example, +.Dq "-m macppc" +implies +.Dq "-p powerpc" . +Some aliases for +.Ar machine Ns / Ns Ar machine_arch +pairs are also supported; for example, +.Dq "-m macppc64" +is shorthand for +.Dq "-m macppc -p powerpc64" . +The way +.Nm +handles a +.Ar machine +name without a +.Ar machine_arch +name is intended to be identical to the way the +.Pa build.sh +script in the +.Nx +source tree handles the same situation. +To pass arbitrary values of +.Fl m Ar machine +without any validation, you must also specify +.Fl p Ar machine_arch . +.Sh EXAMPLES +.Bl -tag +.It Li "kver -r 1.5 uname -r" +Run the +.Ql "uname -r" +command with +.Va osrelease +set to +.Ql 1.5 . +.It Li "kver -m i386 chroot ." +Run the +.Ql "chroot ." +command with +.Va machine +set to +.Ql i386 +and with +.Va machine_arch +set to +.Ql i386 +(which is the default +.Va machine_arch +for that +.Va machine ) . +.It Li "kver -m evbmips sysctl hw.machine_arch" +Error, because there is no default +.Va machine_arch +corresponding to +.Dq "-m evbmips" . +.It Li "kver -m evbmips -p mipseb sysctl hw.machine_arch" +Run the +.Ql "sysctl hw.machine_arch" +command with +.Va machine +set to +.Ql evbmips +and +.Va machine_arch +set to +.Ql mipseb . +.El +.Sh SEE ALSO +.Xr kver 3 +.Sh AUTHORS +.An Alan Barrett Aq apb@NetBSD.org diff --git a/pkgtools/libkver/files/kver/kver.sh b/pkgtools/libkver/files/kver/kver.sh new file mode 100644 index 00000000000..75c1b1ad5fc --- /dev/null +++ b/pkgtools/libkver/files/kver/kver.sh @@ -0,0 +1,247 @@ +#!@SH@ + +LIBKVER='@PREFIX@/lib/libkver.so' +EX_USAGE=64 +nl=' +' +tab=' ' + +usage() +{ + cat <<ENDUSAGE; +usage: $0 [-s ostype] [-r osrelease] [-m machine] [-p arch] command [args] +ENDUSAGE +} + +bomb() +{ + echo >&2 "$0: $*" + exit $EX_USAGE +} + +# begin code copied from build.sh {{{ + +# valid_MACHINE_ARCH -- A multi-line string, listing all valid +# MACHINE/MACHINE_ARCH pairs. +# +# Each line contains a MACHINE and MACHINE_ARCH value, an optional ALIAS +# which may be used to refer to the MACHINE/MACHINE_ARCH pair, and an +# optional DEFAULT or NO_DEFAULT keyword. +# +# When a MACHINE corresponds to multiple possible values of +# MACHINE_ARCH, then this table should list all allowed combinations. +# If the MACHINE is associated with a default MACHINE_ARCH (to be +# used when the user specifies the MACHINE but fails to specify the +# MACHINE_ARCH), then one of the lines should have the "DEFAULT" +# keyword. If there is no default MACHINE_ARCH for a particular +# MACHINE, then there should be a line with the "NO_DEFAULT" keyword, +# and with a blank MACHINE_ARCH. +# +valid_MACHINE_ARCH=' +MACHINE=acorn26 MACHINE_ARCH=arm +MACHINE=acorn32 MACHINE_ARCH=arm +MACHINE=algor MACHINE_ARCH=mips64el ALIAS=algor64 +MACHINE=algor MACHINE_ARCH=mipsel DEFAULT +MACHINE=alpha MACHINE_ARCH=alpha +MACHINE=amd64 MACHINE_ARCH=x86_64 +MACHINE=amiga MACHINE_ARCH=m68k +MACHINE=amigappc MACHINE_ARCH=powerpc +MACHINE=arc MACHINE_ARCH=mips64el ALIAS=arc64 +MACHINE=arc MACHINE_ARCH=mipsel DEFAULT +MACHINE=atari MACHINE_ARCH=m68k +MACHINE=bebox MACHINE_ARCH=powerpc +MACHINE=cats MACHINE_ARCH=arm DEFAULT +MACHINE=cats MACHINE_ARCH=earm +MACHINE=cesfic MACHINE_ARCH=m68k +MACHINE=cobalt MACHINE_ARCH=mips64el ALIAS=cobalt64 +MACHINE=cobalt MACHINE_ARCH=mipsel DEFAULT +MACHINE=dreamcast MACHINE_ARCH=sh3el +MACHINE=emips MACHINE_ARCH=mipseb +MACHINE=evbarm MACHINE_ARCH=arm ALIAS=evbarm-el DEFAULT +MACHINE=evbarm MACHINE_ARCH=armeb ALIAS=evbarm-eb +MACHINE=evbarm MACHINE_ARCH=earm ALIAS=evbearm-el +MACHINE=evbarm MACHINE_ARCH=earmeb ALIAS=evbearm-eb +MACHINE=evbmips MACHINE_ARCH= NO_DEFAULT +MACHINE=evbmips MACHINE_ARCH=mips64eb ALIAS=evbmips64-eb +MACHINE=evbmips MACHINE_ARCH=mips64el ALIAS=evbmips64-el +MACHINE=evbmips MACHINE_ARCH=mipseb ALIAS=evbmips-eb +MACHINE=evbmips MACHINE_ARCH=mipsel ALIAS=evbmips-el +MACHINE=evbppc MACHINE_ARCH=powerpc DEFAULT +MACHINE=evbppc MACHINE_ARCH=powerpc64 ALIAS=evbppc64 +MACHINE=evbsh3 MACHINE_ARCH= NO_DEFAULT +MACHINE=evbsh3 MACHINE_ARCH=sh3eb ALIAS=evbsh3-eb +MACHINE=evbsh3 MACHINE_ARCH=sh3el ALIAS=evbsh3-el +MACHINE=ews4800mips MACHINE_ARCH=mipseb +MACHINE=hp300 MACHINE_ARCH=m68k +MACHINE=hp700 MACHINE_ARCH=hppa +MACHINE=hpcarm MACHINE_ARCH=arm +MACHINE=hpcmips MACHINE_ARCH=mipsel +MACHINE=hpcsh MACHINE_ARCH=sh3el +MACHINE=i386 MACHINE_ARCH=i386 +MACHINE=ia64 MACHINE_ARCH=ia64 +MACHINE=ibmnws MACHINE_ARCH=powerpc +MACHINE=iyonix MACHINE_ARCH=arm DEFAULT +MACHINE=iyonix MACHINE_ARCH=earm +MACHINE=landisk MACHINE_ARCH=sh3el +MACHINE=luna68k MACHINE_ARCH=m68k +MACHINE=mac68k MACHINE_ARCH=m68k +MACHINE=macppc MACHINE_ARCH=powerpc DEFAULT +MACHINE=macppc MACHINE_ARCH=powerpc64 ALIAS=macppc64 +MACHINE=mipsco MACHINE_ARCH=mipseb +MACHINE=mmeye MACHINE_ARCH=sh3eb +MACHINE=mvme68k MACHINE_ARCH=m68k +MACHINE=mvmeppc MACHINE_ARCH=powerpc +MACHINE=netwinder MACHINE_ARCH=arm DEFAULT +MACHINE=netwinder MACHINE_ARCH=earm +MACHINE=news68k MACHINE_ARCH=m68k +MACHINE=newsmips MACHINE_ARCH=mipseb +MACHINE=next68k MACHINE_ARCH=m68k +MACHINE=ofppc MACHINE_ARCH=powerpc DEFAULT +MACHINE=ofppc MACHINE_ARCH=powerpc64 ALIAS=ofppc64 +MACHINE=pmax MACHINE_ARCH=mips64el ALIAS=pmax64 +MACHINE=pmax MACHINE_ARCH=mipsel DEFAULT +MACHINE=prep MACHINE_ARCH=powerpc +MACHINE=rs6000 MACHINE_ARCH=powerpc +MACHINE=sandpoint MACHINE_ARCH=powerpc +MACHINE=sbmips MACHINE_ARCH= NO_DEFAULT +MACHINE=sbmips MACHINE_ARCH=mips64eb ALIAS=sbmips64-eb +MACHINE=sbmips MACHINE_ARCH=mips64el ALIAS=sbmips64-el +MACHINE=sbmips MACHINE_ARCH=mipseb ALIAS=sbmips-eb +MACHINE=sbmips MACHINE_ARCH=mipsel ALIAS=sbmips-el +MACHINE=sgimips MACHINE_ARCH=mips64eb ALIAS=sgimips64 +MACHINE=sgimips MACHINE_ARCH=mipseb DEFAULT +MACHINE=shark MACHINE_ARCH=arm DEFAULT +MACHINE=shark MACHINE_ARCH=earm +MACHINE=sparc MACHINE_ARCH=sparc +MACHINE=sparc64 MACHINE_ARCH=sparc64 +MACHINE=sun2 MACHINE_ARCH=m68000 +MACHINE=sun3 MACHINE_ARCH=m68k +MACHINE=vax MACHINE_ARCH=vax +MACHINE=x68k MACHINE_ARCH=m68k +MACHINE=zaurus MACHINE_ARCH=arm DEFAULT +MACHINE=zaurus MACHINE_ARCH=earm +' + +# getarch -- find the default MACHINE_ARCH for a MACHINE, +# or convert an alias to a MACHINE/MACHINE_ARCH pair. +# +# Saves MACHINE in makewrappermachine before possibly modifying MACHINE. +# +# Sets MACHINE and MACHINE_ARCH if the input MACHINE value is +# recognised as an alias, or recognised as a machine that has a default +# MACHINE_ARCH (or that has only one possible MACHINE_ARCH). +# +# Leaves MACHINE and MACHINE_ARCH unchanged if MACHINE is recognised +# as being associated with multiple MACHINE_ARCH values with no default. +# +# Bombs if MACHINE is not recognised. +# +getarch() +{ + local IFS + local found="" + local line + + IFS="${nl}" + makewrappermachine="${MACHINE}" + for line in ${valid_MACHINE_ARCH}; do + line="${line%%#*}" # ignore comments + line="$( IFS=" ${tab}" ; echo $line )" # normalise white space + case "${line} " in + "") + # skip blank lines or comment lines + continue + ;; + *" ALIAS=${MACHINE} "*) + # Found a line with a matching ALIAS=<alias>. + found="$line" + break + ;; + "MACHINE=${MACHINE} "*" NO_DEFAULT"*) + # Found an explicit "NO_DEFAULT" for this MACHINE. + found="$line" + break + ;; + "MACHINE=${MACHINE} "*" DEFAULT"*) + # Found an explicit "DEFAULT" for this MACHINE. + found="$line" + break + ;; + "MACHINE=${MACHINE} "*) + # Found a line for this MACHINE. If it's the + # first such line, then tentatively accept it. + # If it's not the first matching line, then + # remember that there was more than one match. + case "$found" in + '') found="$line" ;; + *) found="MULTIPLE_MATCHES" ; break ;; + esac + ;; + esac + done + + case "$found" in + *NO_DEFAULT*|*MULTIPLE_MATCHES*) + # MACHINE is OK, but MACHINE_ARCH is still unknown + return + ;; + "MACHINE="*" MACHINE_ARCH="*) + # Obey the MACHINE= and MACHINE_ARCH= parts of the line. + IFS=" " + for frag in ${found}; do + case "$frag" in + MACHINE=*|MACHINE_ARCH=*) + eval "$frag" + ;; + esac + done + ;; + *) + bomb "Unknown target MACHINE: ${MACHINE}" + ;; + esac +} + +# end code copied from build.sh }}} + + +# MAIN PROGRAM + +opt_s="" +opt_r="" +opt_m="" +opt_p="" + +while getopts "s:r:m:p:" opt +do + case "$opt" in + s) opt_s="$OPTARG"; export LIBKVER_OSTYPE="$OPTARG" ;; + r) opt_r="$OPTARG"; export LIBKVER_OSRELEASE="$OPTARG" ;; + m) opt_m="$OPTARG"; export LIBKVER_MACHINE="$OPTARG" ;; + p) opt_p="$OPTARG"; export LIBKVER_MACHINE_ARCH="$OPTARG" ;; + *) usage ; exit $EX_USAGE ;; + esac +done +shift $(($OPTIND - 1)) +if [ $# -eq 0 ]; then + usage + exit $EX_USAGE +fi + +# If MACHINE was specified and MACHINE_ARCH was not specified, +# then try to guess MACHINE_ARCH. +if [ -n "$opt_m" ] && [ -z "$opt_p" ]; then + MACHINE="$opt_m" + getarch + if [ -n "$MACHINE_ARCH" ]; then + # in addition to setting MACHINE_ARCH, + # getarch might have modified MACHINE. + export LIBKVER_MACHINE="$MACHINE" + export LIBKVER_MACHINE_ARCH="$MACHINE_ARCH" + else + bomb "'-m ${MACHINE}' needs '-p <machine_arch>'" + fi +fi + +export LD_PRELOAD="${LIBKVER}${LD_PRELOAD:+:}${LD_PRELOAD}" +exec "$@" diff --git a/pkgtools/libkver/files/lib/kver.3 b/pkgtools/libkver/files/lib/kver.3 index 56425ce07a1..c1bece385fe 100644 --- a/pkgtools/libkver/files/lib/kver.3 +++ b/pkgtools/libkver/files/lib/kver.3 @@ -1,13 +1,13 @@ -.\" $NetBSD: kver.3,v 1.2 2004/04/24 10:53:03 grant Exp $ +.\" $NetBSD: kver.3,v 1.3 2012/10/31 14:41:55 apb Exp $ .\" -.Dd December 13, 2003 +.Dd October 31, 2012 .Os .Dt KVER 3 .Sh NAME .Nm kver .Nd override system version library .Sh SYNOPSIS -LD_PRELOAD=.../libkver.so uname -a +LD_PRELOAD=@PREFIX@/lib/libkver.so uname -a .Sh DESCRIPTION The .Nm @@ -16,24 +16,114 @@ library provides implementations of .Xr uname 3 that shadow the real implementation and could be configured to override the information identifying the current system. -The library is usually loaded by the run-time link-editor via the -LD_PRELOAD hook. -.Pp This is useful for, among other things, building packages in a sandbox/chrooted environment for a different .Nx release then the system hosting the sandbox. .Pp -The library must be configured for reporting a specific -.Nx -release or else it emits a warning message on the standard error output. -The value of the environment variable -.Ev LIBKVER_OSRELEASE -or the ``name'' of the file referenced by the symbolic link named -.Pa /libkver_osrelease -are checked in that order for the -.Nx -release number the library should reports information for. +The library is usually loaded by the run-time link-editor via the +LD_PRELOAD hook. +The +.Xr kver 8 +utility provides a simple wrapper for convenience. +.Pp +For each variable that may be overridden, +.Nm +first attempts to obtain an override value from an environment variable; +if the environment variable is not set then it uses +.Xr readlink 3 +to get the target of a symbolic link, and treats that as the override value; +if that also fails, then the variable is not overridden. +If none of the variables are overridden, or if an error occurs, then +the +.Nm +library emits a warning message on the standard error output, +and allows the program to run without any overrides. +.Pp +The following table lists all the variables that may be overridden, +giving the environment variable name, the symbolic link name, +and a description of the way the value is used. +.Pp +.Bl -column "LIBKVER_MACHINE_ARCH" "/libkver_machine_arch" +.It Sy Environment Ta Sy Symlink Ta Sy Description +. +.It Ev LIBKVER_OSTYPE Ta Pa /libkver_ostype Ta +The operating system type, e.g. +.Qq Nx . +Overrides the +.Xr sysctl 7 +variable +.Va kern.ostype . +Overrides the result from +.Xr uname 1 +with the +.Fl s +flag. +Overrides the +.Va sysname +element of the +.Vt "struct utsname" +result from +.Xr uname 3 . +. +.It Ev LIBKVER_OSRELEASE Ta Pa /libkver_osrelease Ta +The operating system release, e.g. +.Qq "6.0_STABLE" . +Overrides the +.Xr sysctl 7 +variable +.Va kern.osrelease . +Overrides the result from +.Xr uname 1 +with the +.Fl r +flag. +Overrides the +.Va release +element of the +.Vt "struct utsname" +result from +.Xr uname 3 . +.Pp +This value is also converted to an integer, which is used to +override the value of the +.Xr sysctl 7 +variable +.Va kern.osrevision . +. +.It Ev LIBKVER_MACHINE Ta Pa /libkver_machine Ta +The operating hardware platform, e.g. +.Dq "amd64" . +Overrides the +.Xr sysctl 7 +variable +.Va hw.machine . +Overrides the result from +.Xr uname 1 +with the +.Fl m +flag. +Overrides the +.Va machine +element of the +.Vt "struct utsname" +result from +.Xr uname 3 . +. +.It Ev LIBKVER_MACHINE_ARCH Ta Pa /libkver_machine_arch Ta +The machine processor architecture, e.g. +.Dq "x86_64" . +Overrides the +.Xr sysctl 7 +variable +.Va hw.machine_arch . +Overrides the result from +.Xr uname 1 +with the +.Fl p +flag. +.El +.Pp .Sh EXAMPLES .Dl env LD_PRELOAD=/lib/libkver.so LIBKVER_OSRELEASE=1.5 uname -r .Pp @@ -41,7 +131,27 @@ release number the library should reports information for. .Dl env LD_PRELOAD=/lib/libkver.so uname -r .Sh SEE ALSO .Xr ld.so 1 , +.Xr uname 1 , .Xr sysctl 3 , +.Xr uname 3 , +.Xr kver 8 +.Sh DIAGNOSTICS +.Bl -diag +.It "libkver: uname" .Xr uname 3 +failed. +.It "libkver: not configured" +None of the configurable variables has been overridden. +.It "libkver: sysctl hw.machine_arch" +.Xr sysctl 3 +failed to retrieve the value of the +.Va hw.machine_arch +variable. +.It "libkver: cannot convert osrelease to osrevision: %s" +The osrelease string could not be converted to an integer for use by the +.Va kern.osrevision +.Xr sysctl 7 +variable. .Sh AUTHORS .An Stoned Elipot Aq seb@NetBSD.org +.An Alan Barrett Aq apb@NetBSD.org diff --git a/pkgtools/libkver/files/lib/kver.c b/pkgtools/libkver/files/lib/kver.c index 7626b44bfbd..28210cfdebe 100644 --- a/pkgtools/libkver/files/lib/kver.c +++ b/pkgtools/libkver/files/lib/kver.c @@ -1,4 +1,4 @@ -/* $NetBSD: kver.c,v 1.10 2011/11/22 18:13:09 joerg Exp $ */ +/* $NetBSD: kver.c,v 1.11 2012/10/31 14:41:55 apb Exp $ */ #define sysctl _sysctl #define uname _uname @@ -19,11 +19,30 @@ #undef sysctl #undef uname -#define KVER_VERSION_FMT "NetBSD %s (LIBKVER) #0: Tue Jan 19 00:00:00 UTC 2038 root@localhost:/sys/arch/%s/compile/LIBKVER" + +#define KVER_VERSION_FMT "%s %s (LIBKVER) #0: Tue Jan 19 00:00:00 UTC 2038 root@localhost:/sys/arch/%s/compile/LIBKVER" #define KVER_NOT_INITIALIZED_OSRELEASE -2 #define KVER_INVALID_OSRELEASE -1 +/* + * How to override the operating system name; e.g. "NetBSD". + * Used by sysctl kern.ostype, uname -s, struct utsname.sysname + */ +#ifndef PATH_LIBKVER_OSTYPE +#define PATH_LIBKVER_OSTYPE "/libkver_ostype" +#endif +#ifndef VAR_LIBKVER_OSTYPE +#define VAR_LIBKVER_OSTYPE "LIBKVER_OSTYPE" +#endif + +/* + * How to override the operating system release level; e.g. "6.0_STABLE". + * Used by sysctl kern.osrelease, uname -r, struct utsname.release + * + * This is also coverted to an integer, e.g. 601000000, + * for use by sysctl.kern.osrevision. + */ #ifndef PATH_LIBKVER_OSRELEASE #define PATH_LIBKVER_OSRELEASE "/libkver_osrelease" #endif @@ -31,12 +50,37 @@ #define VAR_LIBKVER_OSRELEASE "LIBKVER_OSRELEASE" #endif +/* + * How to override the machine hardware platform, e.g. "i386". + * Used by sysctl hw.machine, uname -m, struct utsname.machine. + */ +#ifndef PATH_LIBKVER_MACHINE +#define PATH_LIBKVER_MACHINE "/libkver_machine" +#endif +#ifndef VAR_LIBKVER_MACHINE +#define VAR_LIBKVER_MACHINE "LIBKVER_MACHINE" +#endif + +/* + * How to override the machine processor architecture, e.g. "i386". + * Used by sysctl hw.machine_arch, uname -p. + */ +#ifndef PATH_LIBKVER_MACHINE_ARCH +#define PATH_LIBKVER_MACHINE_ARCH "/libkver_machine_arch" +#endif +#ifndef VAR_LIBKVER_MACHINE_ARCH +#define VAR_LIBKVER_MACHINE_ARCH "LIBKVER_MACHINE_ARCH" +#endif + static struct kver { + char ostype[_SYS_NMLN]; char osrelease[_SYS_NMLN]; int osrevision; char version[_SYS_NMLN]; + char machine[_SYS_NMLN]; + char machine_arch[_SYS_NMLN]; } kver = { - "", KVER_NOT_INITIALIZED_OSRELEASE, "" + .osrevision = KVER_NOT_INITIALIZED_OSRELEASE }; static struct utsname real_utsname; @@ -48,7 +92,7 @@ static struct utsname real_utsname; #define SYSCTL_STRING(oldp, oldlenp, str) \ if (oldlenp) { \ - len = strlen(str) + 1; \ + size_t len = strlen(str) + 1; \ if (!oldp) \ *oldlenp = len; \ else { \ @@ -129,40 +173,109 @@ str2osrevision(char *s) return KVER_INVALID_OSRELEASE; } +/* + * Initialise one element of struct kver. + * + * The result is based on getenv(envvarname), or readlink(linkname), + * or defaultval. If the provided defaultval is NULL, then the empty + * string is used. + * + * Returns 1 if a non-default value was used, 0 if a default was used. + */ +static int +kver_init_var(char *dst, size_t dstlen, const char *envvar, + const char *linkname, const char *defaultval) +{ + ssize_t len; + char *v; + + v = getenv(envvar); + if (v) { + (void) strlcpy(dst, v, dstlen); + return 1; + } + len = readlink(linkname, dst, dstlen); + if (len > 0) { + dst[len] = '\0'; + return 1; + } + if (defaultval) { + (void) strlcpy(dst, defaultval, dstlen); + return 0; + } + dst[0] = '\0'; + return 0; +} + static void kver_initialize(void) { char *v; int i; + int nok = 0; + char buf[PATH_MAX + 1]; kver.osrevision = KVER_INVALID_OSRELEASE; /* init done */ - v = getenv(VAR_LIBKVER_OSRELEASE); - if (v == NULL) { - char b[MAXPATHLEN + 1]; - i = readlink(PATH_LIBKVER_OSRELEASE, b, sizeof b - 1); - if (i <= 0) { - v = NULL; - } else { - b[i] = '\0'; - v = b; - } + + if (_uname(&real_utsname) != 0) { + warn("libkver: uname"); + return; } - if (v == NULL) { + + /* + * For each variable that can be overridden: try the + * environment variable, then try the symlink, or fall back + * to the unmodified (existing) value. + */ + nok += kver_init_var(kver.ostype, sizeof(kver.ostype), + VAR_LIBKVER_OSTYPE, PATH_LIBKVER_OSTYPE, + real_utsname.sysname); + nok += kver_init_var(kver.osrelease, sizeof(kver.osrelease), + VAR_LIBKVER_OSRELEASE, PATH_LIBKVER_OSRELEASE, + real_utsname.release); + nok += kver_init_var(kver.machine, sizeof(kver.machine), + VAR_LIBKVER_MACHINE, PATH_LIBKVER_MACHINE, + real_utsname.machine); + nok += kver_init_var(kver.machine_arch, sizeof(kver.machine_arch), + VAR_LIBKVER_MACHINE_ARCH, PATH_LIBKVER_MACHINE_ARCH, + ""); + + /* + * warning if the default was used for all variables. no warning + * if at least one non-default value was used. + */ + if (nok == 0) { warnx("libkver: not configured"); return; } - if (_uname(&real_utsname) != 0) { - warn("libkver: uname"); - return; + + /* machine_arch is not in struct utsname, so get default from sysctl */ + if (kver.machine_arch[0] == '\0') { + int mib[] = { CTL_HW, HW_MACHINE_ARCH, 0 }; + int len = sizeof(kver.machine_arch); + int err; + + err = _sysctl(mib, 2, kver.machine_arch, &len, NULL, 0); + if (err < 0) { + warn("libkver: sysctl hw.machine_arch"); + return; + } } - kver.osrevision = str2osrevision(v); + + /* combine several strings to create kver.version */ + (void) snprintf(kver.version, sizeof(kver.version), KVER_VERSION_FMT, + kver.ostype, kver.osrelease, kver.machine); + + /* + * Convert string osrelease to integer osrevision. + * This must be the last thing we do, so that any failure + * resuls in kver.osrelease being set to KVER_INVALID_OSRELEASE. + */ + kver.osrevision = str2osrevision(kver.osrelease); if (kver.osrevision == KVER_INVALID_OSRELEASE) { - warnx("libkver: invalid version: %s", v); - return; + warnx("libkver: cannot convert osrelease to osrevision: %s", + kver.osrelease); } - (void) strncpy(kver.osrelease, v, _SYS_NMLN); - kver.osrelease[_SYS_NMLN - 1] = '\0'; - (void) snprintf(kver.version, _SYS_NMLN, KVER_VERSION_FMT, - kver.osrelease, real_utsname.machine); + return; } @@ -170,6 +283,8 @@ int sysctl(SYSCTL_CONST int *name, u_int namelen, void *oldp, size_t * oldlenp, const void *newp, size_t newlen) { + int r = 0; + _DIAGASSERT(name != NULL); if (newp != (void *) NULL) @@ -181,10 +296,12 @@ sysctl(SYSCTL_CONST int *name, u_int namelen, void *oldp, size_t * oldlenp, if (KVER_BADLY_INITIALIZED || namelen != 2) goto real; - if (name[0] == CTL_KERN) { - size_t len; - int r = 0; + switch (name[0]) { + case CTL_KERN: { switch (name[1]) { + case KERN_OSTYPE: + SYSCTL_STRING(oldp, oldlenp, kver.ostype); + return (r); case KERN_OSRELEASE: SYSCTL_STRING(oldp, oldlenp, kver.osrelease); return (r); @@ -205,6 +322,17 @@ sysctl(SYSCTL_CONST int *name, u_int namelen, void *oldp, size_t * oldlenp, return (r); } } + case CTL_HW: { + switch (name[1]) { + case HW_MACHINE: + SYSCTL_STRING(oldp, oldlenp, kver.machine); + return (r); + case HW_MACHINE_ARCH: + SYSCTL_STRING(oldp, oldlenp, kver.machine_arch); + return (r); + } + } + } real: return (_sysctl(name, namelen, oldp, oldlenp, newp, newlen)); } @@ -217,10 +345,10 @@ uname(struct utsname * n) if (KVER_BADLY_INITIALIZED) return _uname(n); - (void) strncpy(n->sysname, real_utsname.sysname, _SYS_NMLN); + (void) strncpy(n->sysname, kver.ostype, _SYS_NMLN); (void) strncpy(n->nodename, real_utsname.nodename, _SYS_NMLN); (void) strncpy(n->release, kver.osrelease, _SYS_NMLN); (void) strncpy(n->version, kver.version, _SYS_NMLN); - (void) strncpy(n->machine, real_utsname.machine, _SYS_NMLN); + (void) strncpy(n->machine, kver.machine, _SYS_NMLN); return 0; } |