1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1993-1994, by Sun Microsystems, Inc.
24 */
25
26/*
27 * This program replicates the function of the links from a machine name
28 * (such as sun4c) through /usr/kvm to true or false as appropriate.  It
29 * knows the correct special cases.
30 *
31 * IMPORTANT NOTE:
32 *
33 * Do not modify this program to know about additional special cases or
34 * reflect new platforms or instruction set architectures.  This is a
35 * deprecated interface and strictly for backwards compatibility.  This
36 * is psarc/1992/171.  Note the following excerpt from the opinion:
37 *
38 *    It is most important to note that the manual page states in
39 *    the NOTES section:  "The machid family of commands is
40 *    obsolete.  Use uname -p and uname -m instead."
41 *
42 *    The intent of Kernel Architecture Project team is to provide
43 *    only enough functionality to mimic the existing definitions
44 *    on the SPARC and Intel x86 versions of Solaris 2.x.  No new
45 *    identifiers will ever be added to the documented and
46 *    undocumented identifiers listed above.
47 */
48
49#pragma ident	"%Z%%M%	%I%	%E% SMI"
50
51#include <errno.h>
52#include <stdlib.h>
53#include <stdio.h>
54#include <string.h>
55#include <limits.h>
56#include <sys/systeminfo.h>
57
58static char	static_buf[SYS_NMLN];
59static char	*progname;
60
61static void get_info_item(int command, char **buf, long *count);
62
63/* ARGSUSED */
64int
65main(int argc, char *argv[], char *envp[])
66{
67	char	*buf = &static_buf[0];
68	long	buflen = SYS_NMLN;
69
70	if ((progname = strrchr(argv[0], '/')) == NULL)
71		progname = argv[0];
72	else
73		progname++;
74
75	/*
76	 * First possible match is on the processor type.
77	 *
78	 * Special case for architectures: i386 matches i486 and visa versa.
79	 */
80	get_info_item(SI_ARCHITECTURE, &buf, &buflen);
81	if (strcmp(buf, progname) == 0)
82		return (0);
83	if ((strcmp(buf, "i386") == 0 && strcmp(progname, "i486") == 0) ||
84	    (strcmp(buf, "i486") == 0 && strcmp(progname, "i386") == 0))
85		return (0);
86
87	/*
88	 * Next possible match is the machine, or more exactly, the value
89	 * which would be returned by uname(2) in the machine field or uname(1)
90	 * with the -m option.  For historical reasons this is really is
91	 * often a class of platforms which are identical to userland processes
92	 * such as sun4c, sun4m, etc.
93	 */
94	get_info_item(SI_MACHINE, &buf, &buflen);
95	if (strcmp(buf, progname) == 0)
96		return (0);
97
98	/*
99	 * Finally, match the vendor.  We hardwire in one historical match.
100	 */
101	get_info_item(SI_HW_PROVIDER, &buf, &buflen);
102	if (strcmp(buf, progname) == 0)
103		return (0);
104	if (strcasecmp(buf, "Sun_Microsystems") == 0 &&
105	    strcmp("sun", progname) == 0)
106		return (0);
107
108	return (255);
109}
110
111/*
112 * get_info_item is a wrapper around the sysinfo system call. It makes sure
113 * the buffer is large enough, returning a larger buffer if needed.  On
114 * unrecoverable error, it exits.  An error message doesn't help and makes
115 * this tiny program link stdio and maybe deal with internationalization,
116 * so the best thing is to die silently.  Note that the larger buffer is
117 * retained for later use.  Reality is that the buffer will always be big
118 * enough, but this is coded to the spec rather than implementation.
119 */
120static void
121get_info_item(int command, char **buf, long *count)
122{
123	long	error;
124
125	error = sysinfo(command, *buf, *count);
126	if (error > *count) {
127		*count = error;
128		if (*buf != static_buf) {
129			free(*buf);
130		}
131		*buf = (char *) malloc(*count);
132		error = sysinfo(command, *buf, *count);
133	}
134
135	if (error == -1)
136		exit(-1);
137}
138