Ultrix-3.1/src/cmd/sh5/main.c
/**********************************************************************
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. *
* All Rights Reserved. *
* Reference "/usr/src/COPYRIGHT" for applicable restrictions. *
**********************************************************************/
static char *SCCSID="@(#)main.c 3.0 4/22/86";
/*
* (System V) main.c 1.7
*/
/*
* UNIX shell
*
* Bell Telephone Laboratories
*
*/
#include "defs.h"
#include "sym.h"
#include "timeout.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "dup.h"
#ifdef RES
#include <sgtty.h>
#endif
static BOOL beenhere = FALSE;
char tmpout[20] = "/tmp/sh-";
struct fileblk stdfile;
struct fileblk *standin = &stdfile;
int mailchk = 0;
static char *mailp;
static long *mod_time = 0;
#ifdef pdp11
#include <execargs.h>
#endif
extern int exfile();
extern char *simple();
main(c, v, e)
int c;
char *v[];
char *e[];
{
register int rflag = ttyflg;
int rsflag = 1; /* local restricted flag */
struct namnod *n;
stdsigs();
/*
* initialise storage allocation
*/
stakbot = 0;
addblok((unsigned)0);
/*
* set names from userenv
*/
setup_env();
/*
* 'rsflag' is non-zero if SHELL variable is
* set in environment and contains an'r' in
* the simple file part of the value.
*/
if (n = findnam("SHELL"))
{
if (any('r', simple(n->namval)))
rsflag = 0;
}
/*
* a shell is also restricted if argv(0) has
* an 'r' in its simple name
*/
#ifndef RES
if (c > 0 && any('r', simple(*v)))
rflag = 0;
#endif
hcreate();
set_dotpath();
/*
* look for options
* dolc is $#
*/
dolc = options(c, v);
if (dolc < 2)
{
flags |= stdflg;
{
register char *flagc = flagadr;
while (*flagc)
flagc++;
*flagc++ = STDFLG;
*flagc = 0;
}
}
if ((flags & stdflg) == 0)
dolc--;
dolv = v + c - dolc;
dolc--;
/*
* return here for shell file execution
* but not for parenthesis subshells
*/
setjmp(subshell);
/*
* number of positional parameters
*/
replace(&cmdadr, dolv[0]); /* cmdadr is $0 */
/*
* set pidname '$$'
*/
assnum(&pidadr, getpid());
/*
* set up temp file names
*/
settmp();
/*
* default internal field separators - $IFS
*/
dfault(&ifsnod, sptbnl);
dfault(&mchknod, MAILCHECK);
mailchk = stoi(mchknod.namval);
if ((beenhere++) == FALSE) /* ? profile */
{
if (*(simple(cmdadr)) == '-')
{ /* system profile */
#ifndef RES
if ((input = pathopen(nullstr, sysprofile)) >= 0)
exfile(rflag); /* file exists */
#endif
if ((input = pathopen(nullstr, profile)) >= 0)
{
exfile(rflag);
flags &= ~ttyflg;
}
}
if (rsflag == 0 || rflag == 0)
flags |= rshflg;
/*
* open input file if specified
*/
if (comdiv)
{
estabf(comdiv);
input = -1;
}
else
{
input = ((flags & stdflg) ? 0 : chkopen(cmdadr));
#ifdef ACCT
if (input != 0)
preacct(cmdadr);
#endif
comdiv--;
}
}
#ifdef pdp11
else
*execargs = (char *)dolv; /* for `ps' cmd */
#endif
exfile(0);
done();
}
static int
exfile(prof)
BOOL prof;
{
long mailtime = 0; /* Must not be a register variable */
long curtime = 0;
register int userid;
/*
* move input
*/
if (input > 0)
{
Ldup(input, INIO);
input = INIO;
}
userid = geteuid();
/*
* decide whether interactive
*/
if ((flags & intflg) ||
((flags&oneflg) == 0 &&
isatty(output) &&
isatty(input)) )
{
dfault(&ps1nod, (userid ? stdprompt : supprompt));
dfault(&ps2nod, readmsg);
flags |= ttyflg | prompt;
ignsig(SIGTERM);
if (mailpnod.namflg != N_DEFAULT)
setmail(mailpnod.namval);
else
setmail(mailnod.namval);
}
else
{
flags |= prof;
flags &= ~prompt;
}
if (setjmp(errshell) && prof)
{
close(input);
return;
}
/*
* error return here
*/
loopcnt = peekc = peekn = 0;
fndef = 0;
nohash = 0;
iopend = 0;
if (input >= 0)
initf(input);
/*
* command loop
*/
for (;;)
{
tdystak(0);
stakchk(); /* may reduce sbrk */
exitset();
if ((flags & prompt) && standin->fstak == 0 && !eof)
{
if (mailp)
{
time(&curtime);
if ((curtime - mailtime) >= mailchk)
{
chkmail();
mailtime = curtime;
}
}
prs(ps1nod.namval);
#ifdef TIME_OUT
alarm(TIMEOUT);
#endif
flags |= waiting;
}
trapnote = 0;
peekc = readc();
if (eof)
return;
#ifdef TIME_OUT
alarm(0);
#endif
flags &= ~waiting;
execute(cmd(NL, MTFLG), 0, eflag);
eof |= (flags & oneflg);
}
}
chkpr()
{
if ((flags & prompt) && standin->fstak == 0)
prs(ps2nod.namval);
}
settmp()
{
itos(getpid());
serial = 0;
tmpnam = movstr(numbuf, &tmpout[TMPNAM]);
}
Ldup(fa, fb)
register int fa, fb;
{
#ifdef RES
dup(fa | DUPFLG, fb);
close(fa);
ioctl(fb, FIOCLEX, 0);
#else
if (fa >= 0)
{ close(fb);
fcntl(fa,0,fb); /* normal dup */
close(fa);
fcntl(fb, 2, 1); /* autoclose for fb */
}
#endif
}
chkmail()
{
register char *s = mailp;
register char *save;
long *ptr = mod_time;
char *start;
BOOL flg;
struct stat statb;
while (*s)
{
start = s;
save = 0;
flg = 0;
while (*s)
{
if (*s != COLON)
{
if (*s == '%' && save == 0)
save = s;
s++;
}
else
{
flg = 1;
*s = 0;
}
}
if (save)
*save = 0;
if (*start && stat(start, &statb) >= 0)
{
if(statb.st_size && *ptr
&& statb.st_mtime != *ptr)
{
if (save)
{
prs(save+1);
newline();
}
else
prs(mailmsg);
}
*ptr = statb.st_mtime;
}
else if (*ptr == 0)
*ptr = 1;
if (save)
*save = '%';
if (flg)
*s++ = COLON;
ptr++;
}
}
setmail(mailpath)
char *mailpath;
{
register char *s = mailpath;
register int cnt = 1;
long *ptr;
free(mod_time);
if (mailp = mailpath)
{
while (*s)
{
if (*s == COLON)
cnt += 1;
s++;
}
ptr = mod_time = (long *)alloc(sizeof(long) * cnt);
while (cnt)
{
*ptr = 0;
ptr++;
cnt--;
}
}
}