1/* printenv -- print all or part of environment
2   Copyright (C) 1989-1997, 1999-2005, 2007-2010 Free Software Foundation, Inc.
3
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation, either version 3 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16
17/* Usage: printenv [variable...]
18
19   If no arguments are given, print the entire environment.
20   If one or more variable names are given, print the value of
21   each one that is set, and nothing for ones that are not set.
22
23   Exit status:
24   0 if all variables specified were found
25   1 if not
26   2 if some other error occurred
27
28   David MacKenzie and Richard Mlynarik */
29
30#include <config.h>
31#include <stdio.h>
32#include <sys/types.h>
33#include <getopt.h>
34
35#include "system.h"
36
37/* Exit status for syntax errors, etc.  */
38enum { PRINTENV_FAILURE = 2 };
39
40/* The official name of this program (e.g., no `g' prefix).  */
41#define PROGRAM_NAME "printenv"
42
43#define AUTHORS \
44  proper_name ("David MacKenzie"), \
45  proper_name ("Richard Mlynarik")
46
47static struct option const longopts[] =
48{
49  {"null", no_argument, NULL, '0'},
50  {GETOPT_HELP_OPTION_DECL},
51  {GETOPT_VERSION_OPTION_DECL},
52  {NULL, 0, NULL, 0}
53};
54
55void
56usage (int status)
57{
58  if (status != EXIT_SUCCESS)
59    fprintf (stderr, _("Try `%s --help' for more information.\n"),
60             program_name);
61  else
62    {
63      printf (_("\
64Usage: %s [OPTION]... [VARIABLE]...\n\
65Print the values of the specified environment VARIABLE(s).\n\
66If no VARIABLE is specified, print name and value pairs for them all.\n\
67\n\
68"),
69              program_name);
70      fputs (_("\
71  -0, --null     end each output line with 0 byte rather than newline\n\
72"), stdout);
73      fputs (HELP_OPTION_DESCRIPTION, stdout);
74      fputs (VERSION_OPTION_DESCRIPTION, stdout);
75      printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
76      emit_ancillary_info ();
77    }
78  exit (status);
79}
80
81int
82main (int argc, char **argv)
83{
84  char **env;
85  char *ep, *ap;
86  int i;
87  bool ok;
88  int optc;
89  bool opt_nul_terminate_output = false;
90
91  initialize_main (&argc, &argv);
92  set_program_name (argv[0]);
93  setlocale (LC_ALL, "");
94  bindtextdomain (PACKAGE, LOCALEDIR);
95  textdomain (PACKAGE);
96
97  initialize_exit_failure (PRINTENV_FAILURE);
98  atexit (close_stdout);
99
100  while ((optc = getopt_long (argc, argv, "+iu:0", longopts, NULL)) != -1)
101    {
102      switch (optc)
103        {
104        case '0':
105          opt_nul_terminate_output = true;
106          break;
107        case_GETOPT_HELP_CHAR;
108        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
109        default:
110          usage (PRINTENV_FAILURE);
111        }
112    }
113
114  if (optind >= argc)
115    {
116      for (env = environ; *env != NULL; ++env)
117        printf ("%s%c", *env, opt_nul_terminate_output ? '\0' : '\n');
118      ok = true;
119    }
120  else
121    {
122      int matches = 0;
123
124      for (i = optind; i < argc; ++i)
125        {
126          bool matched = false;
127
128          /* 'printenv a=b' is silent, even if 'a=b=c' is in environ.  */
129          if (strchr (argv[i], '='))
130            continue;
131
132          for (env = environ; *env; ++env)
133            {
134              ep = *env;
135              ap = argv[i];
136              while (*ep != '\0' && *ap != '\0' && *ep++ == *ap++)
137                {
138                  if (*ep == '=' && *ap == '\0')
139                    {
140                      printf ("%s%c", ep + 1,
141                              opt_nul_terminate_output ? '\0' : '\n');
142                      matched = true;
143                      break;
144                    }
145                }
146            }
147
148          matches += matched;
149        }
150
151      ok = (matches == argc - optind);
152    }
153
154  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
155}
156