Ultrix-3.1/src/cmd/sh5/name.c
/**********************************************************************
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. *
* All Rights Reserved. *
* Reference "/usr/src/COPYRIGHT" for applicable restrictions. *
**********************************************************************/
/*
* SCCSID: @(#)name.c 3.0 4/22/86
* (System V) name.c 1.5
*/
/*
* UNIX shell
*
* Bell Telephone Laboratories
*
*/
#include "defs.h"
extern BOOL chkid();
extern char *simple();
extern int mailchk;
struct namnod ps2nod =
{
(struct namnod *)NIL,
&acctnod,
ps2name
};
struct namnod cdpnod =
{
(struct namnod *)NIL,
(struct namnod *)NIL,
cdpname
};
struct namnod pathnod =
{
&mailpnod,
(struct namnod *)NIL,
pathname
};
struct namnod ifsnod =
{
&homenod,
&mailnod,
ifsname
};
struct namnod ps1nod =
{
&pathnod,
&ps2nod,
ps1name
};
struct namnod homenod =
{
&cdpnod,
(struct namnod *)NIL,
homename
};
struct namnod mailnod =
{
(struct namnod *)NIL,
(struct namnod *)NIL,
mailname
};
struct namnod mchknod =
{
&ifsnod,
&ps1nod,
mchkname
};
struct namnod acctnod =
{
(struct namnod *)NIL,
(struct namnod *)NIL,
acctname
};
struct namnod mailpnod =
{
(struct namnod *)NIL,
(struct namnod *)NIL,
mailpname
};
struct namnod *namep = &mchknod;
/* ======== variable and string handling ======== */
syslook(w, syswds, n)
register char *w;
register struct sysnod syswds[];
int n;
{
int low;
int high;
int mid;
register int cond;
if (w == 0 || *w == 0)
return(0);
low = 0;
high = n - 1;
while (low <= high)
{
mid = (low + high) / 2;
if ((cond = cf(w, syswds[mid].sysnam)) < 0)
high = mid - 1;
else if (cond > 0)
low = mid + 1;
else
return(syswds[mid].sysval);
}
return(0);
}
setlist(arg, xp)
register struct argnod *arg;
int xp;
{
if (flags & exportflg)
xp |= N_EXPORT;
while (arg)
{
register char *s = mactrim(arg->argval);
setname(s, xp);
arg = arg->argnxt;
if (flags & execpr)
{
prs(s);
if (arg)
blank();
else
newline();
}
}
}
setname(argi, xp) /* does parameter assignments */
char *argi;
int xp;
{
register char *argscan = argi;
register struct namnod *n;
if (letter(*argscan))
{
while (alphanum(*argscan))
argscan++;
if (*argscan == '=')
{
*argscan = 0; /* make name a cohesive string */
n = lookup(argi);
*argscan++ = '=';
attrib(n, xp);
if (xp & N_ENVNAM)
n->namenv = n->namval = argscan;
else
assign(n, argscan);
return;
}
}
failed(argi, notid);
}
replace(a, v)
register char **a;
char *v;
{
free(*a);
*a = make(v);
}
dfault(n, v)
struct namnod *n;
char *v;
{
if (n->namval == 0)
assign(n, v);
}
assign(n, v)
struct namnod *n;
char *v;
{
if (n->namflg & N_RDONLY)
failed(n->namid, wtfailed);
#ifndef RES
else if (flags & rshflg)
{
if (n == &pathnod || eq(n->namid, "SHELL"))
failed(n->namid, restricted);
}
#endif
else if (n->namflg & N_FUNCTN)
{
func_unhash(n->namid);
freefunc(n);
n->namenv = 0;
n->namflg = N_DEFAULT;
}
if (n == &mchknod)
{
mailchk = stoi(v);
}
replace(&n->namval, v);
attrib(n, N_ENVCHG);
if (n == &pathnod)
{
zaphash();
set_dotpath();
return;
}
if (flags & prompt)
{
if ((n == &mailpnod) || (n == &mailnod && mailpnod.namflg == N_DEFAULT))
setmail(n->namval);
}
}
readvar(names)
char **names;
{
struct fileblk fb;
register struct fileblk *f = &fb;
register char c;
register int rc = 0;
struct namnod *n = lookup(*names++); /* done now to avoid storage mess */
char *rel = (char *)relstak();
push(f);
initf(dup(0));
if (lseek(0, 0L, 1) == -1)
f->fsiz = 1;
/*
* strip leading IFS characters
*/
while ((any((c = nextc(0)), ifsnod.namval)) && !(eolchar(c)))
;
for (;;)
{
if ((*names && any(c, ifsnod.namval)) || eolchar(c))
{
zerostak();
assign(n, absstak(rel));
setstak(rel);
if (*names)
n = lookup(*names++);
else
n = 0;
if (eolchar(c))
{
break;
}
else /* strip imbedded IFS characters */
{
while ((any((c = nextc(0)), ifsnod.namval)) &&
!(eolchar(c)))
;
}
}
else
{
pushstak(c);
c = nextc(0);
if (eolchar(c))
{
char *top = staktop;
while (any(*(--top), ifsnod.namval))
;
staktop = top + 1;
}
}
}
while (n)
{
assign(n, nullstr);
if (*names)
n = lookup(*names++);
else
n = 0;
}
if (eof)
rc = 1;
lseek(0, (long)(f->fnxt - f->fend), 1);
pop();
return(rc);
}
assnum(p, i)
char **p;
int i;
{
itos(i);
replace(p, numbuf);
}
char *
make(v)
char *v;
{
register char *p;
if (v)
{
movstr(v, p = alloc(length(v)));
return(p);
}
else
return(0);
}
struct namnod *
lookup(nam)
register char *nam;
{
register struct namnod *nscan = namep;
register struct namnod **prev;
int LR;
if (!chkid(nam))
failed(nam, notid);
while (nscan)
{
if ((LR = cf(nam, nscan->namid)) == 0)
return(nscan);
else if (LR < 0)
prev = &(nscan->namlft);
else
prev = &(nscan->namrgt);
nscan = *prev;
}
/*
* add name node
*/
nscan = (struct namnod *)alloc(sizeof *nscan);
nscan->namlft = nscan->namrgt = (struct namnod *)NIL;
nscan->namid = make(nam);
nscan->namval = 0;
nscan->namflg = N_DEFAULT;
nscan->namenv = 0;
return(*prev = nscan);
}
BOOL
chkid(nam)
char *nam;
{
register char *cp = nam;
if (!letter(*cp))
return(FALSE);
else
{
while (*++cp)
{
if (!alphanum(*cp))
return(FALSE);
}
}
return(TRUE);
}
static int (*namfn)();
namscan(fn)
int (*fn)();
{
namfn = fn;
namwalk(namep);
}
static int
namwalk(np)
register struct namnod *np;
{
if (np)
{
namwalk(np->namlft);
(*namfn)(np);
namwalk(np->namrgt);
}
}
printnam(n)
struct namnod *n;
{
register char *s;
sigchk();
if (n->namflg & N_FUNCTN)
{
prs_buff(n->namid);
prs_buff("(){\n");
prf(n->namenv);
prs_buff("\n}\n");
}
else if (s = n->namval)
{
prs_buff(n->namid);
prc_buff('=');
prs_buff(s);
prc_buff(NL);
}
}
static char *
staknam(n)
register struct namnod *n;
{
register char *p;
p = movstr(n->namid, staktop);
p = movstr("=", p);
p = movstr(n->namval, p);
return(getstak(p + 1 - (char *)(stakbot)));
}
static int namec;
exname(n)
register struct namnod *n;
{
register int flg = n->namflg;
if (flg & N_ENVCHG)
{
if (flg & N_EXPORT)
{
free(n->namenv);
n->namenv = make(n->namval);
}
else
{
free(n->namval);
n->namval = make(n->namenv);
}
}
if (!(flg & N_FUNCTN))
n->namflg = N_DEFAULT;
if (n->namval)
namec++;
}
printro(n)
register struct namnod *n;
{
if (n->namflg & N_RDONLY)
{
prs_buff(readonly);
prc_buff(SP);
prs_buff(n->namid);
prc_buff(NL);
}
}
printexp(n)
register struct namnod *n;
{
if (n->namflg & N_EXPORT)
{
prs_buff(export);
prc_buff(SP);
prs_buff(n->namid);
prc_buff(NL);
}
}
setup_env()
{
register char **e = environ;
while (*e)
setname(*e++, N_ENVNAM);
}
static char **argnam;
pushnam(n)
struct namnod *n;
{
if (n->namval)
*argnam++ = staknam(n);
}
char **
setenv()
{
register char **er;
namec = 0;
namscan(exname);
argnam = er = (char **)getstak(namec * BYTESPERWORD + BYTESPERWORD);
namscan(pushnam);
*argnam++ = 0;
return(er);
}
struct namnod *
findnam(nam)
register char *nam;
{
register struct namnod *nscan = namep;
int LR;
if (!chkid(nam))
return(0);
while (nscan)
{
if ((LR = cf(nam, nscan->namid)) == 0)
return(nscan);
else if (LR < 0)
nscan = nscan->namlft;
else
nscan = nscan->namrgt;
}
return(0);
}
unset_name(name)
register char *name;
{
register struct namnod *n;
if (n = findnam(name))
{
if (n->namflg & N_RDONLY)
failed(name, wtfailed);
if (n == &pathnod ||
n == &ifsnod ||
n == &ps1nod ||
n == &ps2nod ||
n == &mchknod)
{
failed(name, badunset);
}
#ifndef RES
if ((flags & rshflg) && eq(name, "SHELL"))
failed(name, restricted);
#endif
if (n->namflg & N_FUNCTN)
{
func_unhash(name);
freefunc(n);
}
else
{
free(n->namval);
free(n->namenv);
}
n->namval = n->namenv = 0;
n->namflg = N_DEFAULT;
if (flags & prompt)
{
if (n == &mailpnod)
setmail(mailnod.namval);
else if (n == &mailnod && mailpnod.namflg == N_DEFAULT)
setmail(0);
}
}
}