=== pkgtools/libkver/PLIST ================================================================== --- pkgtools/libkver/PLIST (revision 1571) +++ pkgtools/libkver/PLIST (revision 1574) @@ -3,6 +3,9 @@ lib/libkver.so lib/libkver.so.1 lib/libkver.so.1.0 +sbin/kver +man/cat8/kver.0 +man/man8/kver.8 man/cat3/kver.0 man/man3/kver.3 ${PLIST.sysctl}sbin/sysctl === pkgtools/libkver/Makefile ================================================================== --- pkgtools/libkver/Makefile (revision 1571) +++ pkgtools/libkver/Makefile (revision 1574) @@ -18,7 +18,7 @@ NO_PKGTOOLS_REQD_CHECK= yes USE_BSD_MAKEFILE= yes -VERSION= 0.6 +VERSION= 0.7 ONLY_FOR_PLATFORM= NetBSD-*-* @@ -34,6 +34,13 @@ FILES_SUBST+= HAS_SYSCTL=false .endif +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 man/man8 man/cat8 INSTALLATION_DIRS+= lib man/man3 man/cat3 .if empty(LDD_SYSCTL:M*libc*) INSTALLATION_DIRS+= sbin === pkgtools/libkver/files/lib/kver.3 ================================================================== --- pkgtools/libkver/files/lib/kver.3 (revision 1571) +++ pkgtools/libkver/files/lib/kver.3 (revision 1574) @@ -1,13 +1,13 @@ .\" $NetBSD: kver.3,v 1.2 2004/04/24 10:53:03 grant Exp $ .\" -.Dd December 13, 2003 +.Dd Ocrober 30, 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 @@ .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,26 @@ .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 === pkgtools/libkver/files/lib/kver.c ================================================================== --- pkgtools/libkver/files/lib/kver.c (revision 1571) +++ pkgtools/libkver/files/lib/kver.c (revision 1574) @@ -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 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; } === pkgtools/libkver/files/kver (new directory) ================================================================== === pkgtools/libkver/files/kver/Makefile ================================================================== --- pkgtools/libkver/files/kver/Makefile (revision 1571) +++ pkgtools/libkver/files/kver/Makefile (revision 1574) @@ -0,0 +1,4 @@ +MAN= kver.8 +SCRIPTS= kver.sh + +.include Property changes on: pkgtools/libkver/files/kver/Makefile ___________________________________________________________________ Name: svn:eol-style +native === pkgtools/libkver/files/kver/kver.8 ================================================================== --- pkgtools/libkver/files/kver/kver.8 (revision 1571) +++ pkgtools/libkver/files/kver/kver.8 (revision 1574) @@ -0,0 +1,85 @@ +.\" $NetBSD$ +.\" +.Dd October 30, 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 m Ar machine_arch +The machine processor architecture, e.g. +.Dq "x86_64" . +Sets the +.Ev LIBKVER_MACHINE_ARCH +environment variable. +.El +.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 . +.El +.Sh SEE ALSO +.Xr kver 3 +.Sh AUTHORS +.An Alan Barrett Aq apb@NetBSD.org === pkgtools/libkver/files/kver/kver.sh ================================================================== --- pkgtools/libkver/files/kver/kver.sh (revision 1571) +++ pkgtools/libkver/files/kver/kver.sh (revision 1574) @@ -0,0 +1,30 @@ +#!@SH@ + +LIBKVER='@PREFIX@/lib/libkver.so' +EX_USAGE=64 + +usage() +{ + cat <&1