/* uname -- print system information                                            This is the uname utility
                                                                                
   Copyright (C) 1989-2018 Free Software Foundation, Inc.                       
                                                                                
   This program is free software: you can redistribute it and/or modify         
   it under the terms of the GNU General Public License as published by         
   the Free Software Foundation, either version 3 of the License, or            
   (at your option) any later version.                                          
                                                                                
   This program is distributed in the hope that it will be useful,              
   but WITHOUT ANY WARRANTY; without even the implied warranty of               
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                
   GNU General Public License for more details.                                 
                                                                                
   You should have received a copy of the GNU General Public License            
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */   The GNUv3 license
                                                                                
/* Written by David MacKenzie <djm@gnu.ai.mit.edu> */                           
                                                                                
#include <config.h>                                                             Provides system specific information
#include <stdio.h>                                                              Provides standard I/O capability
#include <sys/types.h>                                                          Provides system data types
#include <sys/utsname.h>                                                        ...!includes auto-comment...
#include <getopt.h>                                                             ...!includes auto-comment...
                                                                                
#if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H                                       Line 26
# include <sys/systeminfo.h>                                                    Line 27
#endif                                                                          Line 28
                                                                                
#if HAVE_SYS_SYSCTL_H                                                           Line 30
# if HAVE_SYS_PARAM_H                                                           Line 31
#  include <sys/param.h> /* needed for OpenBSD 3.0 */                           Line 32
# endif                                                                         Line 33
# include <sys/sysctl.h>                                                        Line 34
# ifdef HW_MODEL                                                                Line 35
#  ifdef HW_MACHINE_ARCH                                                        Line 36
/* E.g., FreeBSD 4.5, NetBSD 1.5.2 */                                           
#   define UNAME_HARDWARE_PLATFORM HW_MODEL                                     Line 38
#   define UNAME_PROCESSOR HW_MACHINE_ARCH                                      Line 39
#  else                                                                         Line 40
/* E.g., OpenBSD 3.0 */                                                         
#   define UNAME_PROCESSOR HW_MODEL                                             Line 42
#  endif                                                                        Line 43
# endif                                                                         Line 44
#endif                                                                          Line 45
                                                                                
#ifdef __APPLE__                                                                Line 47
# include <mach/machine.h>                                                      Line 48
# include <mach-o/arch.h>                                                       Line 49
#endif                                                                          Line 50
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "uname.h"                                                              ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME (uname_mode == UNAME_UNAME ? "uname" : "arch")             Line 59
                                                                                
#define AUTHORS proper_name ("David MacKenzie")                                 Line 61
#define ARCH_AUTHORS "David MacKenzie", "Karel Zak"                             Line 62
                                                                                
/* Values that are bitwise or'd into 'toprint'. */                              
/* Kernel name. */                                                              
#define PRINT_KERNEL_NAME 1                                                     Line 66
                                                                                
/* Node name on a communications network. */                                    
#define PRINT_NODENAME 2                                                        Line 69
                                                                                
/* Kernel release. */                                                           
#define PRINT_KERNEL_RELEASE 4                                                  Line 72
                                                                                
/* Kernel version. */                                                           
#define PRINT_KERNEL_VERSION 8                                                  Line 75
                                                                                
/* Machine hardware name. */                                                    
#define PRINT_MACHINE 16                                                        Line 78
                                                                                
/* Processor type. */                                                           
#define PRINT_PROCESSOR 32                                                      Line 81
                                                                                
/* Hardware platform.  */                                                       
#define PRINT_HARDWARE_PLATFORM 64                                              Line 84
                                                                                
/* Operating system.  */                                                        
#define PRINT_OPERATING_SYSTEM 128                                              Line 87
                                                                                
static struct option const uname_long_options[] =                               Line 89
{                                                                               
  {"all", no_argument, NULL, 'a'},                                              Line 91
  {"kernel-name", no_argument, NULL, 's'},                                      Line 92
  {"sysname", no_argument, NULL, 's'}, /* Obsolescent.  */                      Line 93
  {"nodename", no_argument, NULL, 'n'},                                         Line 94
  {"kernel-release", no_argument, NULL, 'r'},                                   Line 95
  {"release", no_argument, NULL, 'r'},  /* Obsolescent.  */                     Line 96
  {"kernel-version", no_argument, NULL, 'v'},                                   Line 97
  {"machine", no_argument, NULL, 'm'},                                          Line 98
  {"processor", no_argument, NULL, 'p'},                                        Line 99
  {"hardware-platform", no_argument, NULL, 'i'},                                Line 100
  {"operating-system", no_argument, NULL, 'o'},                                 Line 101
  {GETOPT_HELP_OPTION_DECL},                                                    Line 102
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 103
  {NULL, 0, NULL, 0}                                                            Line 104
};                                                                              Block 1
                                                                                
static struct option const arch_long_options[] =                                Line 107
{                                                                               
  {GETOPT_HELP_OPTION_DECL},                                                    Line 109
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 110
  {NULL, 0, NULL, 0}                                                            Line 111
};                                                                              Block 2
                                                                                
void                                                                            Line 114
usage (int status)                                                              Line 115
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 117
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 119
    {                                                                           
      printf (_("Usage: %s [OPTION]...\n"), program_name);                      Line 121
                                                                                
      if (uname_mode == UNAME_UNAME)                                            Line 123
        {                                                                       
          fputs (_("\                                                           Line 125
Print certain system information.  With no OPTION, same as -s.\n\               Line 126
\n\                                                                             
  -a, --all                print all information, in the following order,\n\    Line 128
                             except omit -p and -i if unknown:\n\               Line 129
  -s, --kernel-name        print the kernel name\n\                             Line 130
  -n, --nodename           print the network node hostname\n\                   Line 131
  -r, --kernel-release     print the kernel release\n\                          Line 132
"), stdout);                                                                    Line 133
          fputs (_("\                                                           Line 134
  -v, --kernel-version     print the kernel version\n\                          Line 135
  -m, --machine            print the machine hardware name\n\                   Line 136
  -p, --processor          print the processor type (non-portable)\n\           Line 137
  -i, --hardware-platform  print the hardware platform (non-portable)\n\        Line 138
  -o, --operating-system   print the operating system\n\                        Line 139
"), stdout);                                                                    Line 140
        }                                                                       
      else                                                                      Line 142
        {                                                                       
          fputs (_("\                                                           Line 144
Print machine architecture.\n\                                                  Line 145
\n\                                                                             
"), stdout);                                                                    Line 147
        }                                                                       
                                                                                
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 150
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 151
      emit_ancillary_info (PROGRAM_NAME);                                       Line 152
    }                                                                           
  exit (status);                                                                Line 154
}                                                                               Block 3
                                                                                
/* Print ELEMENT, preceded by a space if something has already been             
   printed.  */                                                                 
                                                                                
static void                                                                     Line 160
print_element (char const *element)                                             Line 161
{                                                                               
  static bool printed;                                                          Line 163
  if (printed)                                                                  Line 164
    putchar (' ');                                                              Line 165
  printed = true;                                                               Line 166
  fputs (element, stdout);                                                      Line 167
}                                                                               Block 4
                                                                                
                                                                                
/* Set all the option flags according to the switches specified.                
   Return the mask indicating which elements to print.  */                      
                                                                                
static int                                                                      Line 174
decode_switches (int argc, char **argv)                                         Line 175
{                                                                               
  int c;                                                                        Line 177
  unsigned int toprint = 0;                                                     Line 178
                                                                                
  if (uname_mode == UNAME_ARCH)                                                 Line 180
    {                                                                           
      while ((c = getopt_long (argc, argv, "",                                  Line 182
                               arch_long_options, NULL)) != -1)                 Line 183
        {                                                                       
          switch (c)                                                            Line 185
            {                                                                   
            case_GETOPT_HELP_CHAR;                                              Line 187
                                                                                
            case_GETOPT_VERSION_CHAR (PROGRAM_NAME, ARCH_AUTHORS);              Line 189
                                                                                
            default:                                                            Line 191
              usage (EXIT_FAILURE);                                             Line 192
            }                                                                   
        }                                                                       
      toprint = PRINT_MACHINE;                                                  Line 195
    }                                                                           
  else                                                                          Line 197
    {                                                                           
      while ((c = getopt_long (argc, argv, "asnrvmpio",                         Line 199
                               uname_long_options, NULL)) != -1)                Line 200
        {                                                                       
          switch (c)                                                            Line 202
            {                                                                   
            case 'a':                                                           Line 204
              toprint = UINT_MAX;                                               Line 205
              break;                                                            Line 206
                                                                                
            case 's':                                                           Line 208
              toprint |= PRINT_KERNEL_NAME;                                     Line 209
              break;                                                            Line 210
                                                                                
            case 'n':                                                           Line 212
              toprint |= PRINT_NODENAME;                                        Line 213
              break;                                                            Line 214
                                                                                
            case 'r':                                                           Line 216
              toprint |= PRINT_KERNEL_RELEASE;                                  Line 217
              break;                                                            Line 218
                                                                                
            case 'v':                                                           Line 220
              toprint |= PRINT_KERNEL_VERSION;                                  Line 221
              break;                                                            Line 222
                                                                                
            case 'm':                                                           Line 224
              toprint |= PRINT_MACHINE;                                         Line 225
              break;                                                            Line 226
                                                                                
            case 'p':                                                           Line 228
              toprint |= PRINT_PROCESSOR;                                       Line 229
              break;                                                            Line 230
                                                                                
            case 'i':                                                           Line 232
              toprint |= PRINT_HARDWARE_PLATFORM;                               Line 233
              break;                                                            Line 234
                                                                                
            case 'o':                                                           Line 236
              toprint |= PRINT_OPERATING_SYSTEM;                                Line 237
              break;                                                            Line 238
                                                                                
            case_GETOPT_HELP_CHAR;                                              Line 240
                                                                                
            case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                   Line 242
                                                                                
            default:                                                            Line 244
              usage (EXIT_FAILURE);                                             Line 245
            }                                                                   
        }                                                                       
    }                                                                           
                                                                                
  if (argc != optind)                                                           Line 250
    {                                                                           
      error (0, 0, _("extra operand %s"), quote (argv[optind]));                Line 252
      usage (EXIT_FAILURE);                                                     Line 253
    }                                                                           
                                                                                
  return toprint;                                                               Line 256
}                                                                               Block 5
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 260
{                                                                               
  static char const unknown[] = "unknown";                                      Line 262
                                                                                
  /* Mask indicating which elements to print. */                                
  unsigned int toprint = 0;                                                     Line 265
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  toprint = decode_switches (argc, argv);                                       Line 275
                                                                                
  if (toprint == 0)                                                             Line 277
    toprint = PRINT_KERNEL_NAME;                                                Line 278
                                                                                
  if (toprint                                                                   Line 280
       & (PRINT_KERNEL_NAME | PRINT_NODENAME | PRINT_KERNEL_RELEASE             Line 281
          | PRINT_KERNEL_VERSION | PRINT_MACHINE))                              Line 282
    {                                                                           
      struct utsname name;                                                      Line 284
                                                                                
      if (uname (&name) == -1)                                                  Line 286
        die (EXIT_FAILURE, errno, _("cannot get system name"));                 Line 287
                                                                                
      if (toprint & PRINT_KERNEL_NAME)                                          Line 289
        print_element (name.sysname);                                           Line 290
      if (toprint & PRINT_NODENAME)                                             Line 291
        print_element (name.nodename);                                          Line 292
      if (toprint & PRINT_KERNEL_RELEASE)                                       Line 293
        print_element (name.release);                                           Line 294
      if (toprint & PRINT_KERNEL_VERSION)                                       Line 295
        print_element (name.version);                                           Line 296
      if (toprint & PRINT_MACHINE)                                              Line 297
        print_element (name.machine);                                           Line 298
    }                                                                           
                                                                                
  if (toprint & PRINT_PROCESSOR)                                                Line 301
    {                                                                           
      char const *element = unknown;                                            Line 303
#if HAVE_SYSINFO && defined SI_ARCHITECTURE                                     Line 304
      {                                                                         
        static char processor[257];                                             Line 306
        if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))        Line 307
          element = processor;                                                  Line 308
      }                                                                         
#endif                                                                          Line 310
#ifdef UNAME_PROCESSOR                                                          Line 311
      if (element == unknown)                                                   Line 312
        {                                                                       
          static char processor[257];                                           Line 314
          size_t s = sizeof processor;                                          Line 315
          static int mib[] = { CTL_HW, UNAME_PROCESSOR };                       Line 316
          if (sysctl (mib, 2, processor, &s, 0, 0) >= 0)                        Line 317
            element = processor;                                                Line 318
                                                                                
# ifdef __APPLE__                                                               Line 320
          /* This kludge works around a bug in Mac OS X.  */                    
          if (element == unknown)                                               Line 322
            {                                                                   
              cpu_type_t cputype;                                               Line 324
              size_t cs = sizeof cputype;                                       Line 325
              NXArchInfo const *ai;                                             Line 326
              if (sysctlbyname ("hw.cputype", &cputype, &cs, NULL, 0) == 0      Line 327
                  && (ai = NXGetArchInfoFromCpuType (cputype,                   Line 328
                                                     CPU_SUBTYPE_MULTIPLE))     Line 329
                  != NULL)                                                      Line 330
                element = ai->name;                                             Line 331
                                                                                
              /* Hack "safely" around the ppc vs. powerpc return value. */      
              if (cputype == CPU_TYPE_POWERPC                                   Line 334
                  && STRNCMP_LIT (element, "ppc") == 0)                         Line 335
                element = "powerpc";                                            Line 336
            }                                                                   
# endif                                                                         Line 338
        }                                                                       
#endif                                                                          Line 340
      if (! (toprint == UINT_MAX && element == unknown))                        Line 341
        print_element (element);                                                Line 342
    }                                                                           
                                                                                
  if (toprint & PRINT_HARDWARE_PLATFORM)                                        Line 345
    {                                                                           
      char const *element = unknown;                                            Line 347
#if HAVE_SYSINFO && defined SI_PLATFORM                                         Line 348
      {                                                                         
        static char hardware_platform[257];                                     Line 350
        if (0 <= sysinfo (SI_PLATFORM,                                          Line 351
                          hardware_platform, sizeof hardware_platform))         Line 352
          element = hardware_platform;                                          Line 353
      }                                                                         
#endif                                                                          Line 355
#ifdef UNAME_HARDWARE_PLATFORM                                                  Line 356
      if (element == unknown)                                                   Line 357
        {                                                                       
          static char hardware_platform[257];                                   Line 359
          size_t s = sizeof hardware_platform;                                  Line 360
          static int mib[] = { CTL_HW, UNAME_HARDWARE_PLATFORM };               Line 361
          if (sysctl (mib, 2, hardware_platform, &s, 0, 0) >= 0)                Line 362
            element = hardware_platform;                                        Line 363
        }                                                                       
#endif                                                                          Line 365
      if (! (toprint == UINT_MAX && element == unknown))                        Line 366
        print_element (element);                                                Line 367
    }                                                                           
                                                                                
  if (toprint & PRINT_OPERATING_SYSTEM)                                         Line 370
    print_element (HOST_OPERATING_SYSTEM);                                      Line 371
                                                                                
  putchar ('\n');                                                               Line 373
                                                                                
  return EXIT_SUCCESS;                                                          Line 375
}                                                                               Block 6