Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/lib5/getenv.c
There are 8 other files named getenv.c in the archive. Click here to see a list.
/*
** GETENV, PUTENV - Get and put value for environment name
**
** Copyright (c) 1987 by Ken Harrenstien, SRI International
**
** Original idea of using logical names from:
** Bill Palmer / Stanford University / November 1984
*/
#include "c-env.h"
#include "stddef.h" /* For NULL */
#ifndef _MAXENVNAME
#define _MAXENVNAME 40 /* Max size of environment name (less 1) */
#endif
struct evar {
struct evar *enext;
char *ename;
char *evalue;
};
#if (SYS_T20+SYS_10X)
#include "jsys.h"
#include "ctype.h" /* For isupper/tolower */
#endif
static struct evar *env_list = 0;
static struct evar *_putenv(), *_sevterm(), *_sevhome();
char *
getenv(name)
char *name;
{
register struct evar *ep;
register char *cp;
/* Search existing env vars for a match */
for (ep = env_list; ep; ep = ep->enext) {
if (strcmp(name, ep->ename)==0) /* If matched exactly, */
return ep->evalue; /* return value for name! */
}
/* No existing match, try to check other sources */
#if SYS_T20
/* For TOPS-20, we use silly hack of having logical name defs
** be environment vars. To avoid conflicts with real device
** names etc, all such vars have "CENV-" prefixed to the normal
** variable name. e.g. "TERM" is looked up as the logical name
** "CENV-TERM:".
*/
{
int acs[5];
char lognam[5 + _MAXENVNAME];
char logbuf[1000]; /* Lots of room */
strncat(strcpy(lognam,"CENV-"), name, _MAXENVNAME-5-1);
acs[1] = _LNSJB; /* First try jobwide logical name */
acs[2] = (int)(lognam-1); /* Need backed-up BP for jsys */
acs[3] = (int)(logbuf-1); /* Store into here */
logbuf[0] = 0; /* Ensure buffer starts clear */
if (jsys(LNMST, acs) == 0) { /* If jobwide failed, */
acs[1] = _LNSSY; /* then try systemwide */
jsys(LNMST, acs);
}
if (logbuf[0]) { /* If we won... */
for (cp = logbuf; *cp; ++cp) /* Convert to lowercase */
if (isupper(*cp))
*cp = tolower(*cp);
ep = _putenv(name, logbuf); /* Store it as env var! */
return (ep ? ep->evalue : NULL); /* and return alloced value */
}
}
#endif /*SYS_T20*/
/* Try checking for specific names which have standard meanings */
if (strcmp(name, "TERM")==0) /* TERMCAP terminal type */
return (ep = _sevterm()) ? ep->evalue : 0;
if (strcmp(name, "HOME")==0) /* User's home directory */
return (ep = _sevhome()) ? ep->evalue : 0;
return NULL; /* Give up, failed */
}
/* PUTENV - based on SYSV description.
** Argument is a string in "name=value" form. Adds this to
** the environment of current process. Not clear if we want to
** emulate the (vague) SYSV description which indicates that putenv
** may only store a pointer, and the actual string buffer remains under
** user control.
*/
int
putenv(namval)
char *namval;
{
register char *np, *cp;
register int i;
register struct evar *ep, *prep;
char name[_MAXENVNAME];
/* Get "name" part isolated in temp buffer (to avoid changing orig str) */
for (i = _MAXENVNAME, cp = name, np = namval; *np != '=';) {
if (*np == 0 || --i > 0) /* If not in name=val format */
return -1; /* then fail */
*cp++ = *np++;
}
*cp = 0; /* Tie off name string */
++np; /* Point to value string */
/* Search existing env vars for a match */
for (ep = env_list, prep = NULL; ep; ep = ep->enext) {
if (strcmp(name, ep->ename)==0) /* If matched exactly, */
break; /* stop loop */
prep = ep; /* Save previous ptr */
}
if (ep == NULL) /* If didn't find, */
return (_putenv(name, np) ? 0 : -1); /* just add it */
if (strlen(np) <= strlen(ep->evalue)) { /* If new string small enuf */
strcpy(ep->evalue, np); /* just copy over old one */
return 0; /* and win! */
}
/* Must delete old entry, then add new one */
if (prep) prep->enext = ep->enext; /* Unlink from list */
else env_list = ep->enext;
free((char *)ep); /* Free up old struct */
return (_putenv(name, np) ? 0 : -1); /* Then add new and return */
}
/* _PUTENV - auxiliary for getenv() and putenv().
** Takes a name/value pair and strings it into the environment
** variable list.
*/
static struct evar *
_putenv(name, value)
char *name, *value;
{
register struct evar *ep;
register int nl, vl;
extern char *malloc();
nl = strlen(name);
vl = strlen(value);
ep = (struct evar *) malloc(sizeof(struct evar) + nl+1 + vl+1);
if (ep != NULL) {
ep->ename = (char *)(ep+1); /* Name starts right after struct */
ep->evalue = ep->ename + nl+1; /* Value right after that */
strcpy(ep->ename, name); /* Copy the strings */
strcpy(ep->evalue, value);
ep->enext = env_list; /* Link into head of list */
env_list = ep;
}
return ep; /* NULL or pointer to new linked-in var */
}
/* Auxiliary routines for specific environment names */
/* Find and set HOME variable */
static struct evar *
_sevhome()
{
register struct evar *ep;
char buf[500];
#if SYS_T20+SYS_T10
int acs[5];
jsys(GJINF, acs); /* Get user # in AC 1 */
acs[2] = acs[1]; /* Set up for DIRST% */
#if SYS_T20
strcpy(buf, "PS:<"); /* on T20 must add punctuation */
acs[1] = (int) (buf+3);
#else /* on 10X system adds punct for us */
acs[1] = (int) (buf-1);
#endif
if (jsys(DIRST, acs)) {
#if SYS_T20
strcat((char *)acs[1], ">");
#endif
return _putenv("HOME", buf);
}
#endif
return NULL;
}
/* Find and set TERM variable */
static struct evar *
_sevterm()
{
#if SYS_T20+SYS_10X
register char *str;
int acs[5];
acs[1] = _CTTRM;
jsys(GTTYP, acs); /* Get our terminal type */
switch (acs[2]) {
default: str = NULL; break; /* If don't know type */
#ifdef _TT33
case _TT33: str = "tty33"; break;
#endif
#ifdef _TT35
case _TT35: str = "tty35"; break;
#endif
#ifdef _TT37
case _TT37: str = "tty37"; break;
#endif
#ifdef _TTEXE
case _TTEXE: str = "execuport"; break; /* Probably not in TERMCAP */
#endif
#ifdef _TTDEF
case _TTDEF: str = "DEFAULT"; break; /* ???? */
#endif
#ifdef _TTIDL
case _TTIDL: str = "IDEAL"; break; /* ???? */
#endif
#ifdef _TTV05
case _TTV05: str = "vt05"; break; /* Not in TERMCAP */
#endif
#ifdef _TTV50
case _TTV50: str = "vt50"; break;
#endif
#ifdef _TTL30
case _TTL30: str = "la30"; break; /* Not in TERMCAP? */
#endif
#ifdef _TTG40
case _TTG40: str = "gt40"; break;
#endif
#ifdef _TTL36
case _TTL36: str = "la36"; break; /* Not in TERMCAP? */
#endif
#ifdef _TTV52
case _TTV52: str = "vt52"; break;
#endif
#ifdef _TT100
case _TT100: str = "vt100"; break;
#endif
#ifdef _TTL38
case _TTL38: str = "la38"; break; /* Not in TERMCAP? */
#endif
#ifdef _TT120
case _TT120: str = "la120"; break;
#endif
#ifdef _TT125
case _TT125: str = "vt125"; break;
#endif
#ifdef _TTK10
case _TTK10: str = "gigi"; break; /* DEC VK100 */
#endif
#ifdef _TT102
case _TT102: str = "vt102"; break;
#endif
#ifdef _TTH19
case _TTH19: str = "h19"; break;
#endif
#ifdef _TT131
case _TT131: str = "vt131"; break; /* Not in TERMCAP? */
#endif
#ifdef _TT200
case _TT200: str = "vt200"; break;
#endif
#ifdef _TTADM
case _TTADM: str = "adm3a"; break;
#endif
#ifdef _TTDAM
case _TTDAM: str = "dm2500"; break;
#endif
#ifdef _TTHP
case _TTHP: str = "hp2645"; break;
#endif
#ifdef _TTHAZ
case _TTHAZ: str = "h1500"; break;
#endif
#ifdef _TT43
case _TT43: str = "tty43"; break;
#endif
#ifdef _TTSRC
case _TTSRC: str = "soroc"; break; /* Soroc 120 */
#endif
#ifdef _TTGIL
case _TTGIL: str = "gillotine"; break; /* Not in TERMCAP? */
#endif
#ifdef _TTTEL
case _TTTEL: str = "t1061"; break; /* Teleray 1061 */
#endif
#ifdef _TTTEK
case _TTTEK: str = "tek4025"; break;
#endif
#ifdef _TTANN
case _TTANN: str = "aaa"; break; /* Ann Arbor */
#endif
#ifdef _TTCPT
case _TTCPT: str = "concept100"; break;
#endif
#ifdef _TTIBM
case _TTIBM: str = "ibm3101"; break; /* IBM 3101-20 */
#endif
#ifdef _TTTVI
case _TTTVI: str = "tvi912"; break;
#endif
#ifdef _TTTK3
case _TTTK3: str = "tek4023"; break;
#endif
#ifdef _TTDM2
case _TTDM2: str = "dm1520"; break;
#endif
#ifdef _TTAMB
case _TTAMB: str = "ambassador"; break; /* Ann Arbor */
#endif
#ifdef _TTESP
case _TTESP: str = "esprit"; break; /* Hazeltine */
#endif
#ifdef _TTFRD
case _TTFRD: str = "freedom100"; break;
#endif
#ifdef _TTFR2
case _TTFR2: str = "freedom200"; break;
#endif
#ifdef _TTANS
case _TTANS: str = "ansi"; break;
#endif
#ifdef _TTAVT
case _TTAVT: str = "avt"; break; /* Concept AVT */
#endif
} /* end of switch on terminal type */
if (str) /* If found something */
return _putenv("TERM", str); /* return that! */
#endif /* T20+10X */
return NULL; /* Fail */
}