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