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 
  58 static char     static_buf[SYS_NMLN];
  59 static char     *progname;
  60 
  61 static void get_info_item(int command, char **buf, long *count);
  62 
  63 /* ARGSUSED */
  64 int
  65 main(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  */
 120 static void
 121 get_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 }