uname.c revision 103837
1/*-
2 * Copyright (c) 2002 Juli Mallett.
3 * Copyright (c) 1993
4 *	The Regents of the University of California.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 *    must display the following acknowledgement:
16 *	This product includes software developed by the University of
17 *	California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <sys/cdefs.h>
36
37__FBSDID("$FreeBSD: head/usr.bin/uname/uname.c 103837 2002-09-23 06:14:13Z jmallett $");
38
39#ifndef lint
40static const char copyright[] =
41"@(#) Copyright (c) 1993\n\
42	The Regents of the University of California.  All rights reserved.\n";
43#endif
44
45#ifndef lint
46static const char sccsid[] = "@(#)uname.c	8.2 (Berkeley) 5/4/95";
47#endif
48
49#include <sys/param.h>
50#include <sys/sysctl.h>
51
52#include <err.h>
53#include <stdio.h>
54#include <stdlib.h>
55#include <unistd.h>
56
57#define	MFLAG	0x01
58#define	NFLAG	0x02
59#define	PFLAG	0x04
60#define	RFLAG	0x08
61#define	SFLAG	0x10
62#define	VFLAG	0x20
63
64typedef void (*get_t)(void);
65get_t get_platform, get_hostname, get_arch, get_release, get_sysname, get_version;
66
67void native_platform(void);
68void native_hostname(void);
69void native_arch(void);
70void native_release(void);
71void native_sysname(void);
72void native_version(void);
73void print_uname(u_int);
74void setup_get(void);
75void usage(void);
76
77char *platform, *hostname, *arch, *release, *sysname, *version;
78int space;
79
80int
81main(int argc, char *argv[])
82{
83	u_int flags;
84	int ch;
85
86	setup_get();
87
88	while ((ch = getopt(argc, argv, "amnprsv")) != -1)
89		switch(ch) {
90		case 'a':
91			flags |= (MFLAG | NFLAG | RFLAG | SFLAG | VFLAG);
92			break;
93		case 'm':
94			flags |= MFLAG;
95			break;
96		case 'n':
97			flags |= NFLAG;
98			break;
99		case 'p':
100			flags |= PFLAG;
101			break;
102		case 'r':
103			flags |= RFLAG;
104			break;
105		case 's':
106			flags |= SFLAG;
107			break;
108		case 'v':
109			flags |= VFLAG;
110			break;
111		case '?':
112		default:
113			usage();
114		}
115
116	argc -= optind;
117	argv += optind;
118
119	if (argc)
120		usage();
121
122	if (!flags)
123		flags |= SFLAG;
124
125	print_uname(flags);
126	exit(0);
127}
128
129#define	CHECK_ENV(opt,var)				\
130do {							\
131	if ((var = getenv("UNAME_" opt)) == NULL) {	\
132		get_##var = native_##var;		\
133	} else {					\
134		get_##var = (get_t)NULL;		\
135	}						\
136} while (0)
137
138void
139setup_get(void)
140{
141	CHECK_ENV("s", sysname);
142	CHECK_ENV("n", hostname);
143	CHECK_ENV("r", release);
144	CHECK_ENV("v", version);
145	CHECK_ENV("m", platform);
146	CHECK_ENV("p", arch);
147}
148
149#define	PRINT_FLAG(flags,flag,var)		\
150	if ((flags & flag) == flag) {		\
151		if (space)			\
152			printf(" ");		\
153		else				\
154			space++;		\
155		if (get_##var != NULL)		\
156			(*get_##var)();		\
157		printf("%s", var);		\
158	}
159
160void
161print_uname(u_int flags)
162{
163	PRINT_FLAG(flags, SFLAG, sysname);
164	PRINT_FLAG(flags, NFLAG, hostname);
165	PRINT_FLAG(flags, RFLAG, release);
166	PRINT_FLAG(flags, VFLAG, version);
167	PRINT_FLAG(flags, MFLAG, platform);
168	PRINT_FLAG(flags, PFLAG, arch);
169	printf("\n");
170}
171
172void
173native_sysname(void)
174{
175	int mib[2];
176	size_t len;
177	static char buf[1024];
178
179	mib[0] = CTL_KERN;
180	mib[1] = KERN_OSTYPE;
181	len = sizeof(buf);
182	if (sysctl(mib, 2, &buf, &len, NULL, 0) == -1)
183		err(1, "sysctl");
184	sysname = buf;
185}
186
187void
188native_hostname(void)
189{
190	int mib[2];
191	size_t len;
192	static char buf[1024];
193
194	mib[0] = CTL_KERN;
195	mib[1] = KERN_HOSTNAME;
196	len = sizeof(buf);
197	if (sysctl(mib, 2, &buf, &len, NULL, 0) == -1)
198		err(1, "sysctl");
199	hostname = buf;
200}
201
202void
203native_release(void)
204{
205	int mib[2];
206	size_t len;
207	static char buf[1024];
208
209	mib[0] = CTL_KERN;
210	mib[1] = KERN_OSRELEASE;
211	len = sizeof(buf);
212	if (sysctl(mib, 2, &buf, &len, NULL, 0) == -1)
213		err(1, "sysctl");
214	release = buf;
215}
216
217void
218native_version(void)
219{
220	int mib[2];
221	size_t len, tlen;
222	char *p;
223	static char buf[1024];
224
225	mib[0] = CTL_KERN;
226	mib[1] = KERN_VERSION;
227	len = sizeof(buf);
228	if (sysctl(mib, 2, &buf, &len, NULL, 0) == -1)
229		err(1, "sysctl");
230	for (p = buf, tlen = len; tlen--; ++p)
231		if (*p == '\n' || *p == '\t')
232			*p = ' ';
233	version = buf;
234}
235
236void
237native_platform(void)
238{
239	int mib[2];
240	size_t len;
241	static char buf[1024];
242
243	mib[0] = CTL_HW;
244	mib[1] = HW_MACHINE;
245	len = sizeof(buf);
246	if (sysctl(mib, 2, &buf, &len, NULL, 0) == -1)
247		err(1, "sysctl");
248	platform = buf;
249}
250
251void
252native_arch(void)
253{
254	int mib[2];
255	size_t len;
256	static char buf[1024];
257
258	mib[0] = CTL_HW;
259	mib[1] = HW_MACHINE_ARCH;
260	len = sizeof(buf);
261	if (sysctl(mib, 2, &buf, &len, NULL, 0) == -1)
262		err(1, "sysctl");
263	arch = buf;
264}
265
266void
267usage(void)
268{
269	fprintf(stderr, "usage: uname [-amnprsv]\n");
270	exit(1);
271}
272