/* printenv -- print all or part of environment                                 This is the printenv 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
                                                                                
/* Usage: printenv [variable...]                                                
                                                                                
   If no arguments are given, print the entire environment.                     
   If one or more variable names are given, print the value of                  
   each one that is set, and nothing for ones that are not set.                 
                                                                                
   Exit status:                                                                 
   0 if all variables specified were found                                      
   1 if not                                                                     
   2 if some other error occurred                                               
                                                                                
   David MacKenzie and Richard Mlynarik */                                      
                                                                                
#include <config.h>                                                             Provides system specific information
#include <stdio.h>                                                              Provides standard I/O capability
#include <sys/types.h>                                                          Provides system data types
#include <getopt.h>                                                             ...!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
                                                                                
/* Exit status for syntax errors, etc.  */                                      
enum { PRINTENV_FAILURE = 2 };                                                  Line 38
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "printenv"                                                 Line 41
                                                                                
#define AUTHORS \                                                               Line 43
  proper_name ("David MacKenzie"), \                                            Line 44
  proper_name ("Richard Mlynarik")                                              Line 45
                                                                                
static struct option const longopts[] =                                         Line 47
{                                                                               
  {"null", no_argument, NULL, '0'},                                             Line 49
  {GETOPT_HELP_OPTION_DECL},                                                    Line 50
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 51
  {NULL, 0, NULL, 0}                                                            Line 52
};                                                                              Block 2
                                                                                
void                                                                            Line 55
usage (int status)                                                              Line 56
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 58
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 60
    {                                                                           
      printf (_("\                                                              Line 62
Usage: %s [OPTION]... [VARIABLE]...\n\                                          Line 63
Print the values of the specified environment VARIABLE(s).\n\                   Line 64
If no VARIABLE is specified, print name and value pairs for them all.\n\        Line 65
\n\                                                                             
"),                                                                             Line 67
              program_name);                                                    Line 68
      fputs (_("\                                                               Line 69
  -0, --null     end each output line with NUL, not newline\n\                  Line 70
"), stdout);                                                                    Line 71
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 72
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 73
      printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);                             Line 74
      emit_ancillary_info (PROGRAM_NAME);                                       Line 75
    }                                                                           
  exit (status);                                                                Line 77
}                                                                               Block 3
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 81
{                                                                               
  char **env;                                                                   Line 83
  char *ep, *ap;                                                                Line 84
  int i;                                                                        Line 85
  bool ok;                                                                      Line 86
  int optc;                                                                     Line 87
  bool opt_nul_terminate_output = false;                                        Line 88
                                                                                
  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
                                                                                
  initialize_exit_failure (PRINTENV_FAILURE);                                   Line 96
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  while ((optc = getopt_long (argc, argv, "+iu:0", longopts, NULL)) != -1)      Line 99
    {                                                                           
      switch (optc)                                                             Line 101
        {                                                                       
        case '0':                                                               Line 103
          opt_nul_terminate_output = true;                                      Line 104
          break;                                                                Line 105
        case_GETOPT_HELP_CHAR;                                                  Line 106
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 107
        default:                                                                Line 108
          usage (PRINTENV_FAILURE);                                             Line 109
        }                                                                       
    }                                                                           
                                                                                
  if (optind >= argc)                                                           Line 113
    {                                                                           
      for (env = environ; *env != NULL; ++env)                                  Line 115
        printf ("%s%c", *env, opt_nul_terminate_output ? '\0' : '\n');          Line 116
      ok = true;                                                                Line 117
    }                                                                           
  else                                                                          Line 119
    {                                                                           
      int matches = 0;                                                          Line 121
                                                                                
      for (i = optind; i < argc; ++i)                                           Line 123
        {                                                                       
          bool matched = false;                                                 Line 125
                                                                                
          /* 'printenv a=b' is silent, even if 'a=b=c' is in environ.  */       
          if (strchr (argv[i], '='))                                            Line 128
            continue;                                                           Line 129
                                                                                
          for (env = environ; *env; ++env)                                      Line 131
            {                                                                   
              ep = *env;                                                        Line 133
              ap = argv[i];                                                     Line 134
              while (*ep != '\0' && *ap != '\0' && *ep++ == *ap++)              Line 135
                {                                                               
                  if (*ep == '=' && *ap == '\0')                                Line 137
                    {                                                           
                      printf ("%s%c", ep + 1,                                   Line 139
                              opt_nul_terminate_output ? '\0' : '\n');          Line 140
                      matched = true;                                           Line 141
                      break;                                                    Line 142
                    }                                                           
                }                                                               
            }                                                                   
                                                                                
          matches += matched;                                                   Line 147
        }                                                                       
                                                                                
      ok = (matches == argc - optind);                                          Line 150
    }                                                                           
                                                                                
  return ok ? EXIT_SUCCESS : EXIT_FAILURE;                                      Line 153
}                                                                               Block 4