ignatz@ihuxx.UUCP (Dave Ihnat, Chicago, IL) (08/30/84)
Following is the source of a rewrite of the 'env' command, as mentioned in net.{unix-wizards|micro|unix}, in shar format. Simply cut on the dotted line and run as a shellscript to extract the source and man page. Please feel free do use and distribute; bug reports/fixes and comments? Mail to me. Dave Ihnat ihuxx!ignatz ------------------------CUT------------------------------------------- echo x - env.c cat >env.c <<'!E!O!F!' /* * env.c - display user environment, or set for command execution * * Copyright (c) 1984 by David M. Ihnat * * Usage: env [-] [ name=val]... [ command [arg]...] * * where: * * - : Only pass on newly-defined names; otherwise, * add and modify as indicated. * * name=val : name-value pairs to be added to the env, or * changed. * * command [arg] : command to be executed with the changed * environment, if any. * * This command is a total rewrite of the command of the same name on * the AT&T Unix(Tm) System V release. There is no proprietary code * involved; it is available for use and distribution, provided these * notices remain intact, and it is not sold for profit. Every * effort was made to recreate the behavior of the 'official' version, * so I would suggest maintaining this congruence. The user assumes all * liability for any damages, real or incidental, arising from use of * this program. Caveat Utilitor! -Dave Ihnat, ihuxx!ignatz */ #include <stdio.h> #define NELTS 128 char *nenv[NELTS]; /* New environment structure */ char **endaddr = &nenv[NELTS-1]; /* A bit of magic from poking around in execvp's namelist. */ extern char **environ; char *empty = NULL; /* For an empty environment pointer */ extern int errno; extern char *sys_errlist[]; main(argc,argv,envp) int argc; char **argv; char **envp; { argc--; argv++; /* First, should the environment be passed through, or not? */ if(argc && strcmp(*argv, "-") == 0) { envp = ∅ /* Throw out the extant environment */ argc--; /* And get past the flag */ argv++; } /* Now, pass on existing arguments */ for(;*envp != NULL; envp++) newval(*envp); /* And add or replace any command-line environment variables */ while(*argv != NULL) { /* Have to check this for end of environment mods/adds */ if(strrchr(*argv,'=') == NULL) break; newval(*argv++); } /* Now, if no command, just print the environment */ environ = nenv; if(*argv == NULL) { while(*environ != NULL) puts(*environ++); exit(0); }else { execvp(*argv,argv); /* Gets environment from 'environ' */ puts(sys_errlist[errno],stderr); puts(": ",stderr); puts(*argv,stderr); putc('\n',stderr); exit(1); } } int newval(newname) char *newname; { register char **eptr = nenv; for(;*eptr != NULL;eptr++) { if(eptr>=endaddr) { puts("too many values in environment\n",stderr); eptr = nenv; while(*eptr != NULL) puts(*eptr++); exit(1); } if(!strncmp(newname,*eptr,(strrchr(*eptr,'=')-2))) { /* Found a match--it's a replacement */ *eptr = newname; return; } } /* New value */ *eptr = newname; } !E!O!F! echo x - env.mp cat >env.mp <<'!E!O!F!' .TH ENV 1 "" .SH NAME env \- set environment for command execution .SH SYNOPSIS \fBenv\fP [\-] [ name=value]... [ command [ arg]... ] .SH DESCRIPTION \fIEnv\fP obtains the current \fIenvironment\fP, modifies it according to its arguments, then executes the command with the modified environment. Arguments of the form \fIname=value\fP are merged into the inherited environment before the command is executed. The \fB\-\fP flag causes the inherited environment to be ignored completely, so that the command is executed with exactly the environment specified by the arguments. .PP If no command is specified, the resulting environment is printed, one name\-value pair per line. .SH SEE ALSO sh(1),exec(2),profile(4),environ(5). .SH CAVEATS This program is a complete rewrite of the Bell Laboratories command of the same name; no part of the original source or manual is included. Therefore, you may feel free to use it, and its source, without violation of \fPany\fP contract agreements. However, I retain the copyright in order to specify it remain available for use by all and sundry, without cost. Feel free to modify as necessary, although I went to great pains to recreate the behavior of the original command; I would suggest this congruence be maintained. .PP Along the same lines, although I've made a reasonable effort to test the behavior of the original \fIenv\fP and reproduce it, there are no guarantees. The user assumes all liability for any loss, either direct or incidental, that may be incurred through use of this command. I do ask that any bugs (and, hopefully, fixes) be reported back to me as encountered. \- David M. Ihnat, ihuxx!ignatz !E!O!F!