|
|
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.