|
|
1.1 root 1: /* env.c - manipulate environment and execute a program
2: in that environment
3: Mly 861126
4:
5: Copyright (C) 1986 Free Software Foundation, Inc.
6:
7: This program is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 1, or (at your option)
10: any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; if not, write to the Free Software
19: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20:
21: In other words, you are welcome to use, share and improve this program.
22: You are forbidden to forbid anyone else to use, share and improve
23: what you give them. Help stamp out software-hoarding! */
24:
25: /*
26:
27: If first argument is "-", then a new environment is constructed
28: from scratch; otherwise the environment is inherited from the parent
29: process, except as modified by other options.
30:
31: So, "env - foo" will invoke the "foo" program in a null environment,
32: whereas "env foo" would invoke "foo" in the same environment as that
33: passed to "env" itself.
34:
35: Subsequent arguments are interpreted as follows:
36:
37: * "variable=value" (ie an arg containing a "=" character)
38: means to set the specified environment variable to that value.
39: `value' may be of zero length ("variable="). Note that setting
40: a variable to a zero-length value is different from unsetting it.
41:
42: * "-u variable" or "-unset variable"
43: means to unset that variable
44: If that variable isn't set, does nothing.
45:
46: * "-s variable value" or "-set variable value"
47: same as "variable=value"
48:
49: * "-" or "--"
50: are used to indicate that the following argument is the program
51: to invoke. This is only necessary when the program's name
52: begins with "-" or contains a "="
53:
54: * anything else
55: The first remaining argument specifies a program to invoke
56: (it is searched for according to the specification of the PATH
57: environment variable) and any arguments following that are
58: passed as arguments to that program
59:
60: If no program-name is specified following the environment
61: specifications the the resulting environment is printed
62: (The is like specifying a program-name of "printenv")
63:
64: Examples:
65: If the environment passed to "env" is
66: { USER=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
67:
68: * "env DISPLAY=gnu:0 nemacs"
69: calls "nemacs" in the envionment
70: { EDITOR=emacs USER=rms DISPLAY=gnu }
71:
72: * "env - USER=foo /hacks/hack bar baz"
73: will call the "hack" program on arguments "bar" and "baz"
74: in an environment in which the only variable is "USER"
75: Note that the "-" option will clear out the PATH variable,
76: so one should be careful to specify in which directory
77: to find the program to call
78:
79: * "env -u EDITOR USER=foo PATH=/energy -- e=mc2 bar baz"
80: The program "/energy/e=mc2" is called with environment
81: { USER=foo PATH=/energy }
82:
83: */
84:
85: #ifdef EMACS
86: #define NO_SHORTNAMES
87: #include "../src/config.h"
88: #endif /* EMACS */
89:
90: #include <stdio.h>
91: #include <errno.h>
92:
93: extern int execvp ();
94: extern char *index ();
95:
96: char *xmalloc (), *xrealloc ();
97: char *concat ();
98:
99: extern char **environ;
100:
101: char **nenv;
102: int nenv_size;
103:
104: char *progname;
105: void setenv ();
106: void fatal ();
107:
108: main (argc, argv, envp)
109: register int argc;
110: register char **argv;
111: char **envp;
112: {
113: register char *tem;
114:
115: progname = argv[0];
116: argc--;
117: argv++;
118:
119: nenv_size = 100;
120: nenv = (char **) xmalloc (nenv_size * sizeof (char *));
121: *nenv = (char *) 0;
122:
123: /* "-" flag means to not inherit parent's environment */
124: if (argc && !strcmp (*argv, "-"))
125: {
126: argc--;
127: argv++;
128: }
129: else
130: /* Else pass on existing env vars. */
131: for (; *envp; envp++)
132: {
133: tem = index (*envp, '=');
134: if (tem)
135: {
136: *tem = '\000';
137: setenv (*envp, tem + 1);
138: }
139: }
140:
141: while (argc > 0)
142: {
143: tem = index (*argv, '=');
144: if (tem)
145: /* If arg contains a "=" it specifies to set a variable */
146: {
147: *tem = '\000';
148: setenv (*argv, tem + 1);
149: argc--; argv++;
150: continue;
151: }
152:
153: if (**argv != '-')
154: /* Remaining args are program name and args to pass it */
155: break;
156:
157: if (argc < 2)
158: fatal ("No argument following \"%s\" switch", *argv);
159: if (!strcmp (*argv, "-u") ||
160: !strcmp (*argv, "-unset"))
161: /* Unset a variable */
162: {
163: argc--; argv++;
164: setenv (*argv, 0);
165: argc--; argv++;
166: }
167: else if (!strcmp (*argv, "-s") ||
168: !strcmp (*argv, "-set"))
169: /* Set a variable */
170: {
171: argc--; argv++;
172: tem = *argv;
173: if (argc < 2)
174: fatal ("No value specified for variable \"%s\"",
175: tem);
176: argc--; argv++;
177: setenv (tem, *argv);
178: argc--; argv++;
179: }
180: else if (!strcmp (*argv, "-") || !strcmp (*argv, "--"))
181: {
182: argc--; argv++;
183: break;
184: }
185: else
186: {
187: fatal ("unknown switch \"%s\"", *argv);
188: }
189: }
190:
191: /* If no program specified print the environment and exit */
192: if (argc <= 0)
193: {
194: while (*nenv)
195: printf ("%s\n", *nenv++);
196: exit (0);
197: }
198: else
199: {
200: extern int errno, sys_nerr;
201: extern char *sys_errlist[];
202:
203: environ = nenv;
204: (void) execvp (*argv, argv);
205:
206: fprintf (stderr, "%s: Cannot execute \"%s\"",
207: progname, *argv);
208: if (errno < sys_nerr)
209: fprintf (stderr, ": %s\n" , sys_errlist[errno]);
210: else
211: putc ('\n', stderr);
212: exit (errno != 0 ? errno : 1);
213: }
214: }
215:
216: void
217: setenv (var, val)
218: register char *var, *val;
219: {
220: register char **e;
221: int len = strlen (var);
222:
223: {
224: register char *tem = index (var, '=');
225: if (tem)
226: fatal ("Environment variable names may not contain \"=\": %s",
227: var);
228: else if (*var == '\000')
229: fatal ("Zero-length environment variable name specified.");
230: }
231:
232: for (e = nenv; *e; e++)
233: if (!strncmp (var, *e, len) &&
234: (*e)[len] == '=')
235: {
236: if (val)
237: goto set;
238: else
239: do { *e = *(e + 1); } while (*e++);
240: return;
241: }
242:
243: if (!val)
244: return; /* Nothing to unset */
245:
246: len = e - nenv;
247: if (len + 1 >= nenv_size)
248: {
249: nenv_size += 100;
250: nenv = (char **) xrealloc (nenv, nenv_size * sizeof (char *));
251: e = nenv + len;
252: }
253:
254: set:
255: val = concat (var, "=", val);
256: if (*e)
257: free (*e);
258: else
259: *(e + 1) = (char *) 0;
260: *e = val;
261: return;
262: }
263:
264: void
265: fatal (msg, arg1, arg2)
266: char *msg, *arg1, *arg2;
267: {
268: fprintf (stderr, "%s: ", progname);
269: fprintf (stderr, msg, arg1, arg2);
270: putc ('\n', stderr);
271: exit (1);
272: }
273:
274:
275: extern char *malloc (), *realloc ();
276:
277: void
278: memory_fatal ()
279: {
280: fatal ("Out of memory");
281: }
282:
283: char *
284: xmalloc (size)
285: int size;
286: {
287: register char *value;
288: value = (char *) malloc (size);
289: if (!value) memory_fatal ();
290: return (value);
291: }
292:
293: char *
294: xrealloc (ptr, size)
295: char *ptr;
296: int size;
297: {
298: register char *value;
299: value = (char *) realloc (ptr, size);
300: if (!value) memory_fatal ();
301: return (value);
302: }
303:
304: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
305:
306: char *
307: concat (s1, s2, s3)
308: char *s1, *s2, *s3;
309: {
310: int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
311: char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
312:
313: strcpy (result, s1);
314: strcpy (result + len1, s2);
315: strcpy (result + len1 + len2, s3);
316: *(result + len1 + len2 + len3) = 0;
317:
318: return result;
319: }
320:
321:
322: /*
323: * Local variables:
324: * compile-command: "cc -g -o env env.c"
325: * end:
326: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.