11590Srgrimes/*-
2103518Sjmallett * Copyright (c) 2002 Juli Mallett.
31590Srgrimes * Copyright (c) 1993
41590Srgrimes *	The Regents of the University of California.  All rights reserved.
51590Srgrimes *
61590Srgrimes * Redistribution and use in source and binary forms, with or without
71590Srgrimes * modification, are permitted provided that the following conditions
81590Srgrimes * are met:
91590Srgrimes * 1. Redistributions of source code must retain the above copyright
101590Srgrimes *    notice, this list of conditions and the following disclaimer.
111590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121590Srgrimes *    notice, this list of conditions and the following disclaimer in the
131590Srgrimes *    documentation and/or other materials provided with the distribution.
141590Srgrimes * 3. All advertising materials mentioning features or use of this software
151590Srgrimes *    must display the following acknowledgement:
161590Srgrimes *	This product includes software developed by the University of
171590Srgrimes *	California, Berkeley and its contributors.
181590Srgrimes * 4. Neither the name of the University nor the names of its contributors
191590Srgrimes *    may be used to endorse or promote products derived from this software
201590Srgrimes *    without specific prior written permission.
211590Srgrimes *
221590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
231590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
241590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
251590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
261590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
271590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
281590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
291590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
301590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
311590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
321590Srgrimes * SUCH DAMAGE.
331590Srgrimes */
341590Srgrimes
3587696Smarkm#include <sys/cdefs.h>
3687696Smarkm
3787696Smarkm__FBSDID("$FreeBSD$");
3887696Smarkm
391590Srgrimes#ifndef lint
4087696Smarkmstatic const char copyright[] =
411590Srgrimes"@(#) Copyright (c) 1993\n\
421590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
4387696Smarkm#endif
441590Srgrimes
451590Srgrimes#ifndef lint
4687696Smarkmstatic const char sccsid[] = "@(#)uname.c	8.2 (Berkeley) 5/4/95";
4787696Smarkm#endif
481590Srgrimes
491590Srgrimes#include <sys/param.h>
501590Srgrimes#include <sys/sysctl.h>
511590Srgrimes
521590Srgrimes#include <err.h>
531590Srgrimes#include <stdio.h>
541590Srgrimes#include <stdlib.h>
5523690Speter#include <unistd.h>
561590Srgrimes
57258394Speter#include <osreldate.h>
58258394Speter
591590Srgrimes#define	MFLAG	0x01
601590Srgrimes#define	NFLAG	0x02
6189346Snyan#define	PFLAG	0x04
6289346Snyan#define	RFLAG	0x08
6389346Snyan#define	SFLAG	0x10
6489346Snyan#define	VFLAG	0x20
65116085Sjmallett#define	IFLAG	0x40
66258394Speter#define	UFLAG	0x80
67258394Speter#define	KFLAG	0x100
68103518Sjmallett
69103518Sjmalletttypedef void (*get_t)(void);
70227191Sedstatic get_t get_ident, get_platform, get_hostname, get_arch,
71258394Speter    get_release, get_sysname, get_kernvers, get_uservers, get_version;
72103518Sjmallett
73227191Sedstatic void native_ident(void);
74227191Sedstatic void native_platform(void);
75227191Sedstatic void native_hostname(void);
76227191Sedstatic void native_arch(void);
77227191Sedstatic void native_release(void);
78227191Sedstatic void native_sysname(void);
79227191Sedstatic void native_version(void);
80258394Speterstatic void native_kernvers(void);
81258394Speterstatic void native_uservers(void);
82227191Sedstatic void print_uname(u_int);
83227191Sedstatic void setup_get(void);
84227191Sedstatic void usage(void);
85103518Sjmallett
86258394Speterstatic char *ident, *platform, *hostname, *arch, *release, *sysname, *version, *kernvers, *uservers;
87227191Sedstatic int space;
88103518Sjmallett
89103518Sjmallettint
90103518Sjmallettmain(int argc, char *argv[])
91103518Sjmallett{
921590Srgrimes	u_int flags;
93103518Sjmallett	int ch;
941590Srgrimes
95103518Sjmallett	setup_get();
96103846Sjmallett	flags = 0;
97103518Sjmallett
98258394Speter	while ((ch = getopt(argc, argv, "aiKmnoprsUv")) != -1)
991590Srgrimes		switch(ch) {
1001590Srgrimes		case 'a':
1011590Srgrimes			flags |= (MFLAG | NFLAG | RFLAG | SFLAG | VFLAG);
1021590Srgrimes			break;
103116085Sjmallett		case 'i':
104116085Sjmallett			flags |= IFLAG;
105116085Sjmallett			break;
106258394Speter		case 'K':
107258394Speter			flags |= KFLAG;
108258394Speter			break;
1091590Srgrimes		case 'm':
1101590Srgrimes			flags |= MFLAG;
1111590Srgrimes			break;
1121590Srgrimes		case 'n':
1131590Srgrimes			flags |= NFLAG;
1141590Srgrimes			break;
11589346Snyan		case 'p':
11689346Snyan			flags |= PFLAG;
11789346Snyan			break;
1181590Srgrimes		case 'r':
1191590Srgrimes			flags |= RFLAG;
1201590Srgrimes			break;
1211590Srgrimes		case 's':
122203042Semaste		case 'o':
1231590Srgrimes			flags |= SFLAG;
1241590Srgrimes			break;
125258394Speter		case 'U':
126258394Speter			flags |= UFLAG;
127258394Speter			break;
1281590Srgrimes		case 'v':
1291590Srgrimes			flags |= VFLAG;
1301590Srgrimes			break;
1311590Srgrimes		case '?':
1321590Srgrimes		default:
1331590Srgrimes			usage();
1341590Srgrimes		}
1351590Srgrimes
1361590Srgrimes	argc -= optind;
1371590Srgrimes	argv += optind;
1381590Srgrimes
1391590Srgrimes	if (argc)
1401590Srgrimes		usage();
1411590Srgrimes
1421590Srgrimes	if (!flags)
1431590Srgrimes		flags |= SFLAG;
1441590Srgrimes
145103518Sjmallett	print_uname(flags);
146103518Sjmallett	exit(0);
147103518Sjmallett}
1481590Srgrimes
149103837Sjmallett#define	CHECK_ENV(opt,var)				\
150103837Sjmallettdo {							\
151103518Sjmallett	if ((var = getenv("UNAME_" opt)) == NULL) {	\
152103837Sjmallett		get_##var = native_##var;		\
153103837Sjmallett	} else {					\
154103837Sjmallett		get_##var = (get_t)NULL;		\
155103837Sjmallett	}						\
156103518Sjmallett} while (0)
157103518Sjmallett
158227191Sedstatic void
159103518Sjmallettsetup_get(void)
160103518Sjmallett{
161103518Sjmallett	CHECK_ENV("s", sysname);
162103518Sjmallett	CHECK_ENV("n", hostname);
163103518Sjmallett	CHECK_ENV("r", release);
164103518Sjmallett	CHECK_ENV("v", version);
165103518Sjmallett	CHECK_ENV("m", platform);
166103518Sjmallett	CHECK_ENV("p", arch);
167116085Sjmallett	CHECK_ENV("i", ident);
168258394Speter	CHECK_ENV("K", kernvers);
169258394Speter	CHECK_ENV("U", uservers);
170103518Sjmallett}
171103518Sjmallett
172103518Sjmallett#define	PRINT_FLAG(flags,flag,var)		\
173103518Sjmallett	if ((flags & flag) == flag) {		\
174103837Sjmallett		if (space)			\
175103837Sjmallett			printf(" ");		\
176103837Sjmallett		else				\
177103837Sjmallett			space++;		\
178103518Sjmallett		if (get_##var != NULL)		\
179103518Sjmallett			(*get_##var)();		\
180103837Sjmallett		printf("%s", var);		\
1811590Srgrimes	}
182103518Sjmallett
183227191Sedstatic void
184103518Sjmallettprint_uname(u_int flags)
185103518Sjmallett{
186103518Sjmallett	PRINT_FLAG(flags, SFLAG, sysname);
187103518Sjmallett	PRINT_FLAG(flags, NFLAG, hostname);
188103518Sjmallett	PRINT_FLAG(flags, RFLAG, release);
189103518Sjmallett	PRINT_FLAG(flags, VFLAG, version);
190103518Sjmallett	PRINT_FLAG(flags, MFLAG, platform);
191103518Sjmallett	PRINT_FLAG(flags, PFLAG, arch);
192116085Sjmallett	PRINT_FLAG(flags, IFLAG, ident);
193258394Speter	PRINT_FLAG(flags, KFLAG, kernvers);
194258394Speter	PRINT_FLAG(flags, UFLAG, uservers);
195103518Sjmallett	printf("\n");
1961590Srgrimes}
1971590Srgrimes
198103846Sjmallett#define	NATIVE_SYSCTL2_GET(var,mib0,mib1)	\
199227191Sedstatic void					\
200103846Sjmallettnative_##var(void)				\
201103846Sjmallett{						\
202103846Sjmallett	int mib[] = { (mib0), (mib1) };		\
203103846Sjmallett	size_t len;				\
204103846Sjmallett	static char buf[1024];			\
205103846Sjmallett	char **varp = &(var);			\
206103846Sjmallett						\
207103846Sjmallett	len = sizeof buf;			\
208103846Sjmallett	if (sysctl(mib, sizeof mib / sizeof mib[0],	\
209103846Sjmallett	   &buf, &len, NULL, 0) == -1)		\
210103518Sjmallett		err(1, "sysctl");
211103518Sjmallett
212116088Sjmallett#define	NATIVE_SYSCTLNAME_GET(var,name)		\
213227191Sedstatic void					\
214116088Sjmallettnative_##var(void)				\
215116088Sjmallett{						\
216116088Sjmallett	size_t len;				\
217116088Sjmallett	static char buf[1024];			\
218116088Sjmallett	char **varp = &(var);			\
219116088Sjmallett						\
220117137Sjmallett	len = sizeof buf;			\
221116088Sjmallett	if (sysctlbyname(name, &buf, &len, NULL,\
222116088Sjmallett	    0) == -1)				\
223116088Sjmallett		err(1, "sysctlbyname");
224116088Sjmallett
225103846Sjmallett#define	NATIVE_SET				\
226103846Sjmallett	*varp = buf;				\
227103846Sjmallett	return;					\
228103846Sjmallett}	struct __hack
229103518Sjmallett
230103846Sjmallett#define	NATIVE_BUFFER	(buf)
231103846Sjmallett#define	NATIVE_LENGTH	(len)
232103518Sjmallett
233103846SjmallettNATIVE_SYSCTL2_GET(sysname, CTL_KERN, KERN_OSTYPE) {
234103846Sjmallett} NATIVE_SET;
235103518Sjmallett
236103846SjmallettNATIVE_SYSCTL2_GET(hostname, CTL_KERN, KERN_HOSTNAME) {
237103846Sjmallett} NATIVE_SET;
238103518Sjmallett
239103846SjmallettNATIVE_SYSCTL2_GET(release, CTL_KERN, KERN_OSRELEASE) {
240103846Sjmallett} NATIVE_SET;
241103846Sjmallett
242103846SjmallettNATIVE_SYSCTL2_GET(version, CTL_KERN, KERN_VERSION) {
243103846Sjmallett	size_t n;
244103518Sjmallett	char *p;
245103518Sjmallett
246103846Sjmallett	p = NATIVE_BUFFER;
247103846Sjmallett	n = NATIVE_LENGTH;
248103846Sjmallett	for (; n--; ++p)
249103518Sjmallett		if (*p == '\n' || *p == '\t')
250103518Sjmallett			*p = ' ';
251103846Sjmallett} NATIVE_SET;
252103518Sjmallett
253103846SjmallettNATIVE_SYSCTL2_GET(platform, CTL_HW, HW_MACHINE) {
254103846Sjmallett} NATIVE_SET;
255103518Sjmallett
256103846SjmallettNATIVE_SYSCTL2_GET(arch, CTL_HW, HW_MACHINE_ARCH) {
257103846Sjmallett} NATIVE_SET;
258103518Sjmallett
259116088SjmallettNATIVE_SYSCTLNAME_GET(ident, "kern.ident") {
260116085Sjmallett} NATIVE_SET;
261116085Sjmallett
262227191Sedstatic void
263258394Speternative_uservers(void)
264258394Speter{
265258394Speter	static char buf[128];
266258394Speter
267258394Speter	snprintf(buf, sizeof(buf), "%d", __FreeBSD_version);
268258394Speter	uservers = buf;
269258394Speter}
270258394Speter
271258394Speterstatic void
272258394Speternative_kernvers(void)
273258394Speter{
274258394Speter	static char buf[128];
275258394Speter
276258394Speter	snprintf(buf, sizeof(buf), "%d", getosreldate());
277258394Speter	kernvers = buf;
278258394Speter}
279258394Speter
280258394Speterstatic void
281102944Sdwmaloneusage(void)
2821590Srgrimes{
283258394Speter	fprintf(stderr, "usage: uname [-aiKmnoprsUv]\n");
2841590Srgrimes	exit(1);
2851590Srgrimes}
286