|
|
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: NO WARRANTY
8:
9: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
10: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
11: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
12: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
13: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
14: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
15: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
16: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
17: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
18: CORRECTION.
19:
20: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
21: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
22: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
23: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
24: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
25: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
26: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
27: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
28: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
29: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
30:
31: GENERAL PUBLIC LICENSE TO COPY
32:
33: 1. You may copy and distribute verbatim copies of this source file
34: as you receive it, in any medium, provided that you conspicuously
35: and appropriately publish on each copy a valid copyright notice
36: "Copyright (C) 1986 Free Software Foundation, Inc.", and include
37: following the copyright notice a verbatim copy of the above disclaimer
38: of warranty and of this License.
39:
40: 2. You may modify your copy or copies of this source file or
41: any portion of it, and copy and distribute such modifications under
42: the terms of Paragraph 1 above, provided that you also do the following:
43:
44: a) cause the modified files to carry prominent notices stating
45: that you changed the files and the date of any change; and
46:
47: b) cause the whole of any work that you distribute or publish,
48: that in whole or in part contains or is a derivative of this
49: program or any part thereof, to be licensed at no charge to all
50: third parties on terms identical to those contained in this
51: License Agreement (except that you may choose to grant more extensive
52: warranty protection to some or all third parties, at your option).
53:
54: c) You may charge a distribution fee for the physical act of
55: transferring a copy, and you may at your option offer warranty
56: protection in exchange for a fee.
57:
58: Mere aggregation of another unrelated program with this program (or its
59: derivative) on a volume of a storage or distribution medium does not bring
60: the other program under the scope of these terms.
61:
62: 3. You may copy and distribute this program (or a portion or derivative
63: of it, under Paragraph 2) in object code or executable form under the terms
64: of Paragraphs 1 and 2 above provided that you also do one of the following:
65:
66: a) accompany it with the complete corresponding machine-readable
67: source code, which must be distributed under the terms of
68: Paragraphs 1 and 2 above; or,
69:
70: b) accompany it with a written offer, valid for at least three
71: years, to give any third party free (except for a nominal
72: shipping charge) a complete machine-readable copy of the
73: corresponding source code, to be distributed under the terms of
74: Paragraphs 1 and 2 above; or,
75:
76: c) accompany it with the information you received as to where the
77: corresponding source code may be obtained. (This alternative is
78: allowed only for noncommercial distribution and only if you
79: received the program in object code or executable form alone.)
80:
81: For an executable file, complete source code means all the source code for
82: all modules it contains; but, as a special exception, it need not include
83: source code for modules which are standard libraries that accompany the
84: operating system on which the executable file runs.
85:
86: 4. You may not copy, sublicense, distribute or transfer this program
87: except as expressly provided under this License Agreement. Any attempt
88: otherwise to copy, sublicense, distribute or transfer this program is void and
89: your rights to use the program under this License agreement shall be
90: automatically terminated. However, parties who have received computer
91: software programs from you with this License Agreement will not have
92: their licenses terminated so long as such parties remain in full compliance.
93:
94: 5. If you wish to incorporate parts of this program into other free
95: programs whose distribution conditions are different, write to the Free
96: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
97: worked out a simple rule that can be stated here, but we will often permit
98: this. We will be guided by the two goals of preserving the free status of
99: all derivatives of our free software and of promoting the sharing and reuse of
100: software.
101:
102: In other words, you are welcome to use, share and improve this program.
103: You are forbidden to forbid anyone else to use, share and improve
104: what you give them. Help stamp out software-hoarding! */
105:
106: /*
107:
108: If first argument is "-", then a new environment is constructed
109: from scratch; otherwise the environment is inherited from the parent
110: process, except as modified by other options.
111:
112: So, "env - foo" will invoke the "foo" program in a null environment,
113: whereas "env foo" would invoke "foo" in the same environment as that
114: passed to "env" itself.
115:
116: Subsequent arguments are interpreted as follows:
117:
118: * "variable=value" (ie an arg containing a "=" character)
119: means to set the specified environment variable to that value.
120: `value' may be of zero length ("variable="). Note that setting
121: a variable to a zero-length value is different from unsetting it.
122:
123: * "-u variable" or "-unset variable"
124: means to unset that variable
125: If that variable isn't set, does nothing.
126:
127: * "-s variable value" or "-set variable value"
128: same as "variable=value"
129:
130: * "-" or "--"
131: are used to indicate that the following argument is the program
132: to invoke. This is only necessary when the program's name
133: begins with "-" or contains a "="
134:
135: * anything else
136: The first remaining argument specifies a program to invoke
137: (it is searched for according to the specification of the PATH
138: environment variable) and any arguments following that are
139: passed as arguments to that program
140:
141: If no program-name is specified following the environment
142: specifications the the resulting environment is printed
143: (The is like specifying a program-name of "printenv")
144:
145: Examples:
146: If the environment passed to "env" is
147: { USER=rms EDITOR=emacs PATH=.:/gnubin:/hacks }
148:
149: * "env DISPLAY=gnu:0 nemacs"
150: calls "nemacs" in the envionment
151: { EDITOR=emacs USER=rms DISPLAY=gnu }
152:
153: * "env - USER=foo /hacks/hack bar baz"
154: will call the "hack" program on arguments "bar" and "baz"
155: in an environment in which the only variable is "USER"
156: Note that the "-" option will clear out the PATH variable,
157: so one should be careful to specify in which directory
158: to find the program to call
159:
160: * "env -u EDITOR USER=foo PATH=/energy -- e=mc2 bar baz"
161: The program "/energy/e=mc2" is called with environment
162: { USER=foo PATH=/energy }
163:
164: */
165:
166: #ifdef EMACS
167: #define NO_SHORTNAMES
168: #include "../src/config.h"
169: #endif /* EMACS */
170:
171: #include <stdio.h>
172:
173: extern int execvp ();
174: extern char *index ();
175:
176: char *xmalloc (), *xrealloc ();
177: char *concat ();
178:
179: extern char **environ;
180:
181: char **nenv;
182: int nenv_size;
183:
184: char *progname;
185: void setenv ();
186: void fatal ();
187:
188: main (argc, argv, envp)
189: register int argc;
190: register char **argv;
191: char **envp;
192: {
193: register char *tem;
194:
195: progname = argv[0];
196: argc--;
197: argv++;
198:
199: nenv_size = 100;
200: nenv = (char **) xmalloc (nenv_size * sizeof (char *));
201: *nenv = (char *) 0;
202:
203: /* "-" flag means to not inherit parent's environment */
204: if (argc && !strcmp (*argv, "-"))
205: {
206: argc--;
207: argv++;
208: }
209: else
210: /* Else pass on existing env vars. */
211: for (; *envp; envp++)
212: {
213: tem = index (*envp, '=');
214: if (tem)
215: {
216: *tem = '\000';
217: setenv (*envp, tem + 1);
218: }
219: }
220:
221: while (argc > 0)
222: {
223: tem = index (*argv, '=');
224: if (tem)
225: /* If arg contains a "=" it specifies to set a variable */
226: {
227: *tem = '\000';
228: setenv (*argv, tem + 1);
229: argc--; argv++;
230: continue;
231: }
232:
233: if (**argv != '-')
234: /* Remaining args are program name and args to pass it */
235: break;
236:
237: if (argc < 2)
238: fatal ("No argument following \"%s\" switch", *argv);
239: if (!strcmp (*argv, "-u") ||
240: !strcmp (*argv, "-unset"))
241: /* Unset a variable */
242: {
243: argc--; argv++;
244: setenv (*argv, 0);
245: argc--; argv++;
246: }
247: else if (!strcmp (*argv, "-s") ||
248: !strcmp (*argv, "-set"))
249: /* Set a variable */
250: {
251: argc--; argv++;
252: tem = *argv;
253: if (argc < 2)
254: fatal ("No value specified for variable \"%s\"",
255: tem);
256: argc--; argv++;
257: setenv (tem, *argv);
258: argc--; argv++;
259: }
260: else if (!strcmp (*argv, "-") || !strcmp (*argv, "--"))
261: {
262: argc--; argv++;
263: break;
264: }
265: else
266: {
267: fatal ("unknown switch \"%s\"", *argv);
268: }
269: }
270:
271: /* If no program specified print the environment and exit */
272: if (argc <= 0)
273: {
274: while (*nenv)
275: printf ("%s\n", *nenv++);
276: exit (0);
277: }
278: else
279: {
280: extern int errno, sys_nerr;
281: extern char *sys_errlist[];
282:
283: environ = nenv;
284: (void) execvp (*argv, argv);
285:
286: fprintf (stderr, "%s: Cannot execute \"%s\"",
287: progname, *argv);
288: if (errno < sys_nerr)
289: fprintf (stderr, ": %s\n" , sys_errlist[errno]);
290: else
291: putc ('\n', stderr);
292: exit (errno != 0 ? errno : 1);
293: }
294: }
295:
296: void
297: setenv (var, val)
298: register char *var, *val;
299: {
300: register char **e;
301: int len = strlen (var);
302:
303: {
304: register char *tem = index (var, '=');
305: if (tem)
306: fatal ("Environment variable names may not contain \"=\": %s",
307: var);
308: else if (*var == '\000')
309: fatal ("Zero-length environment variable name specified.");
310: }
311:
312: for (e = nenv; *e; e++)
313: if (!strncmp (var, *e, len) &&
314: (*e)[len] == '=')
315: {
316: if (val)
317: goto set;
318: else
319: do { *e = *(e + 1); } while (*e++);
320: return;
321: }
322:
323: if (!val)
324: return; /* Nothing to unset */
325:
326: len = e - nenv;
327: if (len + 1 >= nenv_size)
328: {
329: nenv_size += 100;
330: nenv = (char **) xrealloc (nenv, nenv_size * sizeof (char *));
331: e = nenv + len;
332: }
333:
334: set:
335: val = concat (var, "=", val);
336: if (*e)
337: free (*e);
338: else
339: *(e + 1) = (char *) 0;
340: *e = val;
341: return;
342: }
343:
344: void
345: fatal (msg, arg1, arg2)
346: char *msg, *arg1, *arg2;
347: {
348: fprintf (stderr, "%s: ", progname);
349: fprintf (stderr, msg, arg1, arg2);
350: putc ('\n', stderr);
351: exit (1);
352: }
353:
354:
355: extern char *malloc (), *realloc ();
356:
357: void
358: memory_fatal ()
359: {
360: fatal ("Out of memory");
361: }
362:
363: char *
364: xmalloc (size)
365: int size;
366: {
367: register char *value;
368: value = (char *) malloc (size);
369: if (!value) memory_fatal ();
370: return (value);
371: }
372:
373: char *
374: xrealloc (ptr, size)
375: char *ptr;
376: int size;
377: {
378: register char *value;
379: value = (char *) realloc (ptr, size);
380: if (!value) memory_fatal ();
381: return (value);
382: }
383:
384: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
385:
386: char *
387: concat (s1, s2, s3)
388: char *s1, *s2, *s3;
389: {
390: int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
391: char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
392:
393: strcpy (result, s1);
394: strcpy (result + len1, s2);
395: strcpy (result + len1 + len2, s3);
396: *(result + len1 + len2 + len3) = 0;
397:
398: return result;
399: }
400:
401:
402: /*
403: * Local variables:
404: * compile-command: "cc -g -o env env.c"
405: * end:
406: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.