sort: fix hang with sort --compress
[platform/upstream/coreutils.git] / src / printenv.c
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.  */
38 enum { 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
47 static 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
55 void
56 usage (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 (_("\
64 Usage: %s [OPTION]... [VARIABLE]...\n\
65 Print the values of the specified environment VARIABLE(s).\n\
66 If 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
81 int
82 main (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 }