#include "defs.h"
#include "sym.h"
#include "timeout.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "dup.h"
#ifdef RES
#include <sgtty.h>
#endif
pid_t mypid, mypgid, mysid;
static BOOL beenhere = FALSE;
unsigned char tmpout[TMPOUTSZ];
struct fileblk stdfile;
struct fileblk *standin = &stdfile;
int mailchk = 0;
static unsigned char *mailp;
static long *mod_time = 0;
static BOOL login_shell = FALSE;
#if vax
char **execargs = (char **)(0x7ffffffc);
#endif
#if pdp11
char **execargs = (char **)(-2);
#endif
static void exfile();
extern unsigned char *simple();
static void Ldup(int, int);
void settmp(void);
void chkmail(void);
void setmail(unsigned char *);
int
main(int c, char *v[], char *e[])
{
int rflag = ttyflg;
int rsflag = 1;
unsigned char *flagc = flagadr;
struct namnod *n;
mypid = getpid();
mypgid = getpgid(mypid);
mysid = getsid(mypid);
localedir_exists = (access(localedir, F_OK) == 0);
if (stakbot == 0) {
addblok((unsigned)0);
}
if (*simple(v[0]) == '-') {
signal(SIGXCPU, SIG_DFL);
signal(SIGXFSZ, SIG_DFL);
login_shell = TRUE;
}
stdsigs();
setup_env();
if (localedir_exists)
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
if (n = findnam("SHELL")) {
if (eq("rsh", simple(n->namval)))
rsflag = 0;
}
#ifndef RES
if (c > 0 && (eq("rsh", simple(*v)) || eq("-rsh", simple(*v))))
rflag = 0;
#endif
if (eq("jsh", simple(*v)) || eq("-jsh", simple(*v)))
flags |= monitorflg;
hcreate();
set_dotpath();
dolc = options(c, v);
if (dolc < 2) {
flags |= stdflg;
{
while (*flagc)
flagc++;
*flagc++ = STDFLG;
*flagc = 0;
}
}
if ((flags & stdflg) == 0)
dolc--;
if ((flags & privflg) == 0) {
uid_t euid;
gid_t egid;
uid_t ruid;
gid_t rgid;
euid = geteuid();
ruid = getuid();
egid = getegid();
rgid = getgid();
if ((euid != ruid) && (euid < 100))
setuid(ruid);
if ((egid != rgid) && ((egid < 100) && (egid != 1)))
setgid(rgid);
}
dolv = (unsigned char **)v + c - dolc;
dolc--;
if (setjmp(subshell)) {
freejobs();
flags |= subsh;
}
replace(&cmdadr, dolv[0]);
assnum(&pidadr, (long)mypid);
settmp();
assign(&ifsnod, (unsigned char *)sptbnl);
dfault(&mchknod, MAILCHECK);
mailchk = stoi(mchknod.namval);
n = lookup("OPTIND");
assign(n, (unsigned char *)"1");
_sp = 1;
if ((beenhere++) == FALSE)
{
if ((login_shell == TRUE) && (flags & privflg) == 0) {
#ifndef RES
if ((input = pathopen(nullstr, sysprofile)) >= 0)
exfile(rflag);
#endif
if ((input = pathopen(homenod.namval, profile)) >= 0) {
exfile(rflag);
flags &= ~ttyflg;
}
}
if (rsflag == 0 || rflag == 0) {
if ((flags & rshflg) == 0) {
while (*flagc)
flagc++;
*flagc++ = 'r';
*flagc = '\0';
}
flags |= rshflg;
}
if (comdiv) {
estabf(comdiv);
input = -1;
}
else
{
if (flags & stdflg) {
input = 0;
} else {
flags |= forcexit;
input = chkopen(cmdadr, 0);
flags &= ~forcexit;
}
#ifdef ACCT
if (input != 0)
preacct(cmdadr);
#endif
comdiv--;
}
}
#ifdef pdp11
else
*execargs = (char *)dolv;
#endif
exfile(0);
done(0);
}
static void
exfile(int prof)
{
time_t mailtime = 0;
time_t curtime = 0;
if (input > 0) {
Ldup(input, INIO);
input = INIO;
}
setmode(prof);
if (setjmp(errshell) && prof) {
close(input);
(void) endjobs(0);
return;
}
loopcnt = peekc = peekn = 0;
fndef = 0;
nohash = 0;
iopend = 0;
if (input >= 0)
initf(input);
for (;;) {
tdystak(0);
stakchk();
exitset();
if ((flags & prompt) && standin->fstak == 0 && !eof) {
if (mailp) {
time(&curtime);
if ((curtime - mailtime) >= mailchk) {
chkmail();
mailtime = curtime;
}
}
if (trapnote & TRAPSET)
chktrap();
prs(ps1nod.namval);
#ifdef TIME_OUT
alarm(TIMEOUT);
#endif
}
trapnote = 0;
peekc = readwc();
if (eof) {
if (endjobs(JOB_STOPPED))
return;
eof = 0;
}
#ifdef TIME_OUT
alarm(0);
#endif
{
struct trenod *t;
t = cmd(NL, MTFLG);
if (t == NULL && flags & ttyflg)
freejobs();
else
execute(t, 0, eflag);
}
eof |= (flags & oneflg);
}
}
void
chkpr(void)
{
if ((flags & prompt) && standin->fstak == 0)
prs(ps2nod.namval);
}
void
settmp(void)
{
int len;
serial = 0;
if ((len = snprintf((char *)tmpout, TMPOUTSZ, "/tmp/sh%u", mypid)) >=
TMPOUTSZ) {
tmpout_offset = TMPOUTSZ - 1;
} else {
tmpout_offset = len;
}
}
static void
Ldup(int fa, int fb)
{
#ifdef RES
dup(fa | DUPFLG, fb);
close(fa);
ioctl(fb, FIOCLEX, 0);
#else
if (fa >= 0) {
if (fa != fb) {
close(fb);
fcntl(fa, 0, fb);
close(fa);
}
fcntl(fb, 2, 1);
}
#endif
}
void
chkmail(void)
{
unsigned char *s = mailp;
unsigned char *save;
long *ptr = mod_time;
unsigned 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((const char *)start, &statb) >= 0) {
if (statb.st_size && *ptr &&
statb.st_mtime != *ptr) {
if (save) {
prs(save+1);
newline();
}
else
prs(_gettext(mailmsg));
}
*ptr = statb.st_mtime;
} else if (*ptr == 0)
*ptr = 1;
if (save)
*save = '%';
if (flg)
*s++ = COLON;
ptr++;
}
}
void
setmail(unsigned char *mailpath)
{
unsigned char *s = mailpath;
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--;
}
}
}
void
setmode(int prof)
{
if ((flags & intflg) ||
((flags&oneflg) == 0 &&
isatty(output) &&
isatty(input)))
{
dfault(&ps1nod, (geteuid() ? stdprompt : supprompt));
dfault(&ps2nod, readmsg);
flags |= ttyflg | prompt;
if (mailpnod.namflg != N_DEFAULT)
setmail(mailpnod.namval);
else
setmail(mailnod.namval);
startjobs();
}
else
{
flags |= prof;
flags &= ~prompt;
}
}