Files
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

736 lines
11 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)service.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.22.2.1 */
#endif
/*
* UNIX shell
*/
#include "defs.h"
#include <errno.h>
#define ARGMK 01
extern int gsort();
extern char *sysmsg[];
extern short topfd;
/*
* service routines for `execute'
*/
initio(iop, save)
struct ionod *iop;
int save;
{
extern long lseek();
register char *ion;
register int iof, fd;
int ioufd;
short lastfd;
lastfd = topfd;
while (iop)
{
iof = iop->iofile;
ion = mactrim(iop->ioname);
ioufd = iof & IOUFD;
if (*ion && (flags&noexec) == 0)
{
if (save)
{
fdmap[topfd].org_fd = ioufd;
fdmap[topfd++].dup_fd = savefd(ioufd);
}
if (iof & IODOC)
{
struct tempblk tb;
subst(chkopen(ion), (fd = tmpfil(&tb)));
poptemp(); /* pushed in tmpfil() --
bug fix for problem with
in-line scripts
*/
fd = chkopen(tmpout);
unlink(tmpout);
}
else if (iof & IOMOV)
{
if (eq(minus, ion))
{
fd = -1;
close(ioufd);
}
else if ((fd = stoi(ion)) >= USERIO)
failed(ion, badfile);
else
fd = dup(fd);
}
else if ((iof & IOPUT) == 0)
fd = chkopen(ion);
else if (flags & rshflg)
failed(ion, restricted);
else if (iof & IOAPP && (fd = open(ion, 1)) >= 0)
lseek(fd, 0L, 2);
else
fd = create(ion);
if (fd >= 0)
renamefd(fd, ioufd);
}
iop = iop->ionxt;
}
return(lastfd);
}
char *
simple(s)
char *s;
{
char *sname;
sname = s;
while (1)
{
if (any('/', sname))
while (*sname++ != '/')
;
else
return(sname);
}
}
char *
getpath(s)
char *s;
{
register char *path, *newpath;
register int pathlen;
if (any('/', s))
{
if (flags & rshflg)
failed(s, restricted);
/*NOTREACHED*/
else
return(nullstr);
}
else if ((path = pathnod.namval) == 0)
return(defpath);
else {
pathlen = length(path)-1;
/* Add extra ':' if PATH variable ends in ':' */
if(pathlen > 2 && path[pathlen - 1] == ':' && path[pathlen - 2] != ':') {
newpath = locstak();
(void) memcpystak(newpath, path, pathlen);
newpath[pathlen] = ':';
endstak(newpath + pathlen + 1);
return(newpath);
} else
return(cpystak(path));
}
}
pathopen(path, name)
register char *path, *name;
{
register int f;
do
{
path = catpath(path, name);
} while ((f = open(curstak(), 0)) < 0
&& (errno == ENOENT || errno == EACCES || errno == ETIMEDOUT)
&& path);
return(f);
}
char *
catpath(path, name)
register char *path;
char *name;
{
/*
* leaves result on top of stack
*/
register char *scanp = path;
register char *argp = locstak();
while (*scanp && *scanp != COLON)
{
if (argp >= brkend)
growstak(argp);
*argp++ = *scanp++;
}
if (scanp != path)
{
if (argp >= brkend)
growstak(argp);
*argp++ = '/';
}
if (*scanp == COLON)
scanp++;
path = (*scanp ? scanp : 0);
scanp = name;
do
{
if (argp >= brkend)
growstak(argp);
}
while (*argp++ = *scanp++);
return(path);
}
char *
nextpath(path)
register char *path;
{
register char *scanp = path;
while (*scanp && *scanp != COLON)
scanp++;
if (*scanp == COLON)
scanp++;
return(*scanp ? scanp : 0);
}
static char *xecmsg;
static char **xecenv;
static char *execs();
int execa(at, pos)
char *at[];
short pos;
{
register char *path;
register char **t = at;
int cnt;
if ((flags & noexec) == 0)
{
xecmsg = notfound;
path = getpath(*t);
xecenv = setenv();
if (pos > 0)
{
cnt = 1;
while (cnt != pos)
{
++cnt;
path = nextpath(path);
}
execs(path, t);
path = getpath(*t);
}
while (path = execs(path,t))
;
failed(*t, xecmsg);
}
}
static char *
execs(ap, t)
char *ap;
register char *t[];
{
register char *p, *prefix;
prefix = catpath(ap, t[0]);
trim(p = curstak());
sigchk();
execve(p, &t[0] ,xecenv);
switch (errno)
{
case ENOEXEC: /* could be a shell script */
funcnt = 0;
flags = 0;
*flagadr = 0;
comdiv = 0;
ioset = 0;
clearup(); /* remove open files and for loop junk */
if (input)
close(input);
input = chkopen(p);
#ifdef ACCT
preacct(p); /* reset accounting */
#endif
/* is this really a shell script */
{
char c;
if (!isatty(input)) {
read(input, &c, 1);
if ((c < ' ' &&
c != '\n' && c != '\t' && c != '\f') ||
c > '~') {
prs("Cannot exec binary file.\n");
failed(p, badexec);
}
lseek(input, (long) 0, 0);
}
}
/*
* set up local variables to match environment
*/
setvars();
/*
* set up new args
*/
setargs(t);
longjmp(subshell, 1);
default:
scfailed(p);
/*NOTREACHED*/
case EACCES:
case ETIMEDOUT:
xecmsg = scerrmsg();
case ENOENT:
return(prefix);
}
}
/*
* for processes to be waited for
*/
#define MAXP 20
static int pwlist[MAXP];
static int pwc;
postclr()
{
register int *pw = pwlist;
while (pw <= &pwlist[pwc])
*pw++ = 0;
pwc = 0;
}
post(pcsid)
int pcsid;
{
register int *pw = pwlist;
if (pcsid)
{
while (*pw)
pw++;
if (pwc >= MAXP - 1)
pw--;
else
pwc++;
*pw = pcsid;
}
}
await(i, bckg)
int i, bckg;
{
int rc = 0, wx = 0;
int w;
int ipwc = pwc;
post(i);
while (pwc)
{
register int p;
register int sig;
int w_hi;
int found = 0;
{
register int *pw = pwlist;
if (setjmp(INTbuf) == 0)
{
trapjmp = 1;
p = wait(&w);
}
else
p = -1;
trapjmp = 0;
if (wasintr)
{
wasintr = 0;
if (bckg)
{
break;
}
}
while (pw <= &pwlist[ipwc])
{
if (*pw == p)
{
*pw = 0;
pwc--;
found++;
}
else
pw++;
}
}
if (p == -1)
{
if (bckg)
{
register int *pw = pwlist;
while (pw <= &pwlist[ipwc] && i != *pw)
pw++;
if (i == *pw)
{
*pw = 0;
pwc--;
}
} else if(errno == ECHILD)
break;
continue;
}
w_hi = (w >> 8) & LOBYTE;
if (sig = w & 0177)
{
if (sig == 0177) /* ptrace! return */
{
prs("ptrace: ");
sig = w_hi;
}
if (sig > MAXTRAP || sysmsg[sig])
{
if (i != p || (flags & prompt) == 0)
{
prp();
prn(p);
blank();
}
if(sig > MAXTRAP) {
prs("Signal ");
prn(sig);
}
else
prs(sysmsg[sig]);
if (w & 0200)
prs(coredump);
newline();
}
else if (flags & prompt)
newline();
}
if (rc == 0 && found != 0)
rc = (sig ? sig | SIGFLG : w_hi);
wx |= w;
if (p == i)
{
break;
}
}
if (wx && flags & errflg)
exitsh(rc);
flags |= eflag;
exitval = rc;
exitset();
}
BOOL nosubst;
trim(at)
char *at;
{
register char *last;
register char *current;
register char c;
register char q = 0;
nosubst = 0;
if (current = at)
{
last = at;
while (c = *current++)
{
if(c == '\\') { /* remove \ and quoted nulls */
nosubst = 1;
if(c = *current++)
*last++ = c;
} else
*last++ = c;
}
*last = 0;
}
}
char *
mactrim(s)
char *s;
{
register char *t = macro(s);
trim(t);
return(t);
}
char **
scan(argn)
int argn;
{
register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);
register char **comargn, **comargm;
comargn = (char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
comargm = comargn += argn;
*comargn = ENDARGS;
while (argp)
{
*--comargn = argp->argval;
trim(*comargn);
argp = argp->argnxt;
if (argp == 0 || Rcheat(argp) & ARGMK)
{
gsort(comargn, comargm);
comargm = comargn;
}
/* Lcheat(argp) &= ~ARGMK; */
argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
}
return(comargn);
}
static int
gsort(from, to)
char *from[], *to[];
{
int k, m, n;
register int i, j;
if ((n = to - from) <= 1)
return;
for (j = 1; j <= n; j *= 2)
;
for (m = 2 * j - 1; m /= 2; )
{
k = n - m;
for (j = 0; j < k; j++)
{
for (i = j; i >= 0; i -= m)
{
register char **fromi;
fromi = &from[i];
if (cf(fromi[m], fromi[0]) > 0)
{
break;
}
else
{
char *s;
s = fromi[m];
fromi[m] = fromi[0];
fromi[0] = s;
}
}
}
}
}
/*
* Argument list generation
*/
getarg(ac)
struct comnod *ac;
{
register struct argnod *argp;
register int count = 0;
register struct comnod *c;
if (c = ac)
{
argp = c->comarg;
while (argp)
{
count += split(macro(argp->argval),1);
argp = argp->argnxt;
}
}
return(count);
}
static int
split(s) /* blank interpretation routine */
register char *s;
{
register char *argp;
register int c;
register int d;
int count = 0;
for (;;)
{
sigchk();
argp = locstak() + BYTESPERWORD;
while (c = *s++) {
if(c == '\\') { /* skip over quoted characters */
if (argp >= brkend)
growstak(argp);
*argp++ = c;
if (argp >= brkend)
growstak(argp);
*argp++ = *s++;
}
else if (any(c, ifsnod.namval))
break;
else {
if (argp >= brkend)
growstak(argp);
*argp++ = c;
}
}
if (argp == staktop + BYTESPERWORD)
{
if (c)
{
continue;
}
else
{
return(count);
}
}
else if (c == 0)
s--;
/*
* file name generation
*/
argp = endstak(argp);
if ((flags & nofngflg) == 0 &&
(c = expand(((struct argnod *)argp)->argval, 0)))
count += c;
else
{
makearg(argp);
count++;
}
gchain = (struct argnod *)((int)gchain | ARGMK);
}
}
#ifdef ACCT
#include <sys/types.h>
#include "acctdef.h"
#include <sys/acct.h>
#include <sys/times.h>
struct acct sabuf;
struct tms buffer;
extern long times();
static long before;
static int shaccton; /* 0 implies do not write record on exit
1 implies write acct record on exit
*/
/*
* suspend accounting until turned on by preacct()
*/
suspacct()
{
shaccton = 0;
}
preacct(cmdadr)
char *cmdadr;
{
char *simple();
if (acctnod.namval && *acctnod.namval)
{
sabuf.ac_btime = time((long *)0);
before = times(&buffer);
sabuf.ac_uid = getuid();
sabuf.ac_gid = getgid();
movstrn(simple(cmdadr), sabuf.ac_comm, sizeof(sabuf.ac_comm));
shaccton = 1;
}
}
#include <fcntl.h>
doacct()
{
int fd;
long int after;
if (shaccton)
{
after = times(&buffer);
sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
sabuf.ac_etime = compress(after - before);
if ((fd = open(acctnod.namval, O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)
{
write(fd, &sabuf, sizeof(sabuf));
close(fd);
}
}
}
/*
* Produce a pseudo-floating point representation
* with 3 bits base-8 exponent, 13 bits fraction
*/
compress(t)
register time_t t;
{
register exp = 0;
register rund = 0;
while (t >= 8192)
{
exp++;
rund = t & 04;
t >>= 3;
}
if (rund)
{
t++;
if (t >= 8192)
{
t >>= 3;
exp++;
}
}
return((exp << 13) + t);
}
#endif