1/*	$NetBSD: uname.c,v 1.10 1998/11/09 13:24:05 kleink Exp $	*/
2
3/*
4 * Copyright (c) 1994 Winning Strategies, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *      This product includes software developed by Winning Strategies, Inc.
18 * 4. The name of Winning Strategies, Inc. may not be used to endorse or
19 *    promote products derived from this software without specific prior
20 *    written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
35#ifndef lint
36__RCSID("$NetBSD: uname.c,v 1.10 1998/11/09 13:24:05 kleink Exp $");
37#endif /* not lint */
38
39#include <sys/param.h>
40#include <limits.h>
41#include <locale.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <unistd.h>
45#include <err.h>
46#ifdef __APPLE__
47#include <string.h>
48#endif /* __APPLE__ */
49
50#include <sys/sysctl.h>
51#include <sys/utsname.h>
52
53#ifdef __APPLE__
54#include <get_compat.h>
55#else  /* !__APPLE__ */
56#define COMPAT_MODE(a,b) (1)
57#endif /* __APPLE__ */
58
59int	main __P((int, char **));
60static void usage __P((void));
61
62/* Note that PRINT_MACHINE_ARCH is excluded from PRINT_ALL! */
63#define	PRINT_SYSNAME		0x01
64#define	PRINT_NODENAME		0x02
65#define	PRINT_RELEASE		0x04
66#define	PRINT_VERSION		0x08
67#define	PRINT_MACHINE		0x10
68#define	PRINT_MACHINE_ARCH	0x20
69#define	PRINT_ALL		\
70    (PRINT_SYSNAME|PRINT_NODENAME|PRINT_RELEASE|PRINT_VERSION|PRINT_MACHINE)
71
72int
73main(argc, argv)
74	int argc;
75	char **argv;
76{
77	struct utsname u;
78#ifndef __APPLE__
79	char machine_arch[SYS_NMLN];
80#endif /* !__APPLE__ */
81	int c;
82	int space = 0;
83	int print_mask = 0;
84
85	(void)setlocale(LC_ALL, "");
86
87	while ((c = getopt(argc,argv,"amnprsv")) != -1) {
88		switch (c) {
89		case 'a':
90			print_mask |= PRINT_ALL;
91#ifdef __APPLE__
92			if (!COMPAT_MODE("bin/uname", "Unix2003")) {
93				print_mask |= PRINT_MACHINE_ARCH;
94			}
95#endif /* __APPLE__ */
96			break;
97		case 'm':
98			print_mask |= PRINT_MACHINE;
99			break;
100		case 'n':
101			print_mask |= PRINT_NODENAME;
102			break;
103		case 'p':
104			print_mask |= PRINT_MACHINE_ARCH;
105			break;
106		case 'r':
107			print_mask |= PRINT_RELEASE;
108			break;
109		case 's':
110			print_mask |= PRINT_SYSNAME;
111			break;
112		case 'v':
113			print_mask |= PRINT_VERSION;
114			break;
115		default:
116			usage();
117			/* NOTREACHED */
118		}
119	}
120
121	if (optind != argc) {
122		usage();
123		/* NOTREACHED */
124	}
125
126	if (!print_mask) {
127		print_mask = PRINT_SYSNAME;
128	}
129
130	if (uname(&u) != 0) {
131		err(EXIT_FAILURE, "uname");
132		/* NOTREACHED */
133	}
134#ifndef __APPLE__
135	if (print_mask & PRINT_MACHINE_ARCH) {
136		int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
137		size_t len = sizeof (machine_arch);
138
139		if (sysctl(mib, sizeof (mib) / sizeof (mib[0]), machine_arch,
140		    &len, NULL, 0) < 0)
141			err(EXIT_FAILURE, "sysctl");
142	}
143#endif /* !__APPLE__ */
144
145#ifdef __APPLE__
146	/*
147	 * Let's allow the user to override the output of uname via the shell environment.
148	 * This is a useful feature for cross-compiling (eg. during an OS bringup).
149	 * Otherwise, you have to hack your kernel with the desired strings.
150	 */
151	{
152		char *s;
153		s = getenv ("UNAME_SYSNAME");  if (s) strncpy (u.sysname,  s, sizeof (u.sysname));
154		s = getenv ("UNAME_NODENAME"); if (s) strncpy (u.nodename, s, sizeof (u.nodename));
155		s = getenv ("UNAME_RELEASE");  if (s) strncpy (u.release,  s, sizeof (u.release));
156		s = getenv ("UNAME_VERSION");  if (s) strncpy (u.version,  s, sizeof (u.version));
157		s = getenv ("UNAME_MACHINE");  if (s) strncpy (u.machine,  s, sizeof (u.machine));
158	}
159#endif /* __APPLE__ */
160
161	if (print_mask & PRINT_SYSNAME) {
162		space++;
163		fputs(u.sysname, stdout);
164	}
165	if (print_mask & PRINT_NODENAME) {
166		if (space++) putchar(' ');
167		fputs(u.nodename, stdout);
168	}
169	if (print_mask & PRINT_RELEASE) {
170		if (space++) putchar(' ');
171		fputs(u.release, stdout);
172	}
173	if (print_mask & PRINT_VERSION) {
174		if (space++) putchar(' ');
175		fputs(u.version, stdout);
176	}
177	if (print_mask & PRINT_MACHINE) {
178		if (space++) putchar(' ');
179		fputs(u.machine, stdout);
180	}
181	if (print_mask & PRINT_MACHINE_ARCH) {
182		if (space++) putchar(' ');
183#ifndef __APPLE__
184		fputs(machine_arch, stdout);
185#else
186#if defined(__ppc__) || defined(__ppc64__)
187		fputs("powerpc", stdout);
188#elif defined (__i386__) || defined(__x86_64__)
189		fputs("i386", stdout);
190#elif defined(__arm__)
191		fputs("arm", stdout);
192#else
193		fputs("unknown", stdout);
194#endif
195#endif /* __APPLE__ */
196	}
197	putchar('\n');
198
199	exit(EXIT_SUCCESS);
200	/* NOTREACHED */
201}
202
203static void
204usage()
205{
206	fprintf(stderr, "usage: uname [-amnprsv]\n");
207	exit(EXIT_FAILURE);
208}
209