/*
* Copyright 1989 by Rayan S. Zachariassen, all rights reserved.
* This will be free software, but only when it is finished.
*/
/*
* ZShell main and input routines.
*/
#include "hostenv.h"
#ifdef MAILER
#include "sift.h"
#endif /* MAILER */
#include "mailer.h"
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
#include "zmsignal.h"
#include "flags.h"
#include "interpret.h"
#include "shconfig.h"
#include "splay.h"
#include "sh.h"
#include "libc.h"
#include "libsh.h"
struct cmddef commands[] = {
#include "sh-out.i"
};
extern int newcell_gc_interval, D_conscell;
int ncommands = sizeof commands / sizeof commands[0];
struct sptree *spt_funclist = NULL;
struct sptree *spt_builtins = NULL;
struct sptree *spt_searchpath;
int saweof;
FILE *runiofp = NULL;
conscell *commandline = NULL; /* argument to -c option */
const char *progname;
struct osCmd avcmd = { 0, };
char shfl[CHARSETSIZE/NBBY];
int
zshtoplevel(errname)
const char *errname;
{
void *table, *eotable;
int status = 0;
memtypes oval;
setfreefd();
oval = stickymem;
stickymem = MEM_PERM;
saweof = 0;
while (1) {
table = SslWalker(errname, stdout, &eotable);
if (saweof)
break;
if (table == NULL) {
if (isset('i')) {
status = 1; /* syntax error status */
continue;
} else
break;
}
if (isset('n')) {
free((char *)table);
continue;
}
if (isset('W'))
table = optimize(1, table, &eotable);
if (isset('O')) {
table = optimize(0, table, &eotable);
if (isset('V'))
table = optimize(1, table, &eotable);
}
interpret(table, eotable, NULL, &avcmd, &status,
(struct codedesc *)NULL);
}
stickymem = oval;
return status;
}
void
zshprofile(command)
const char *command;
{
memtypes oval = stickymem;
stickymem = MEM_PERM;
commandline = s_pushstack(commandline, command);
stickymem = oval;
}
/* things to do once only, the first time zsh is called */
void
zshinit(argc, argv)
int argc;
const char **argv;
{
int c, errflag, io, uid, loadit;
register struct shCmd *shcmdp;
memtypes oval;
runiofp = stdout;
oval = stickymem;
stickymem = MEM_PERM;
/* check for funny business */
uid = geteuid();
if (uid != getuid()) {
fprintf(stderr, "%s: ruid != euid\n", argv[0]);
exit(1);
}
/* take and stash a snapshot of inherited signal handlers */
trapsnap();
if (spt_funclist == NULL)
spt_funclist = sp_init();
spt_searchpath = sp_init();
/* The Router will initialize this on its own if it needs to */
if (spt_builtins == NULL)
spt_builtins = sp_init();
for (shcmdp = &builtins[0]; shcmdp->name != NULL; ++shcmdp)
sp_install(symbol(shcmdp->name), (void *)shcmdp, 0L, spt_builtins);
TOKEN_NARGS(sBufferSet) = 1;
TOKEN_NARGS(sBufferAppend) = 1;
TOKEN_NARGS(sIOdup) = 1;
TOKEN_NARGS(sIOsetDesc) = 1;
TOKEN_NARGS(sLocalVariable) = 1;
TOKEN_NARGS(sParameter) = 1;
#ifdef MAILER
TOKEN_NARGS(sSiftBufferAppend) = 1;
#endif /* MAILER */
TOKEN_NARGS(sFunction) = -1;
TOKEN_NARGS(sJump) = -1;
TOKEN_NARGS(sJumpFork) = -1;
TOKEN_NARGS(sJumpIfFailure) = -1;
TOKEN_NARGS(sJumpIfSuccess) = -1;
TOKEN_NARGS(sJumpIfNilVariable) = -1;
TOKEN_NARGS(sJumpIfMatch) = -1;
TOKEN_NARGS(sJumpIfFindVarNil) = -1;
TOKEN_NARGS(sJumpIfOrValueNil) = -1;
TOKEN_NARGS(sJumpLoopBreak) = -1;
TOKEN_NARGS(sJumpLoopContinue) = -1;
#ifdef MAILER
TOKEN_NARGS(sSiftCompileRegexp) = -1;
TOKEN_NARGS(sJumpIfRegmatch) = -1;
TOKEN_NARGS(sTSiftCompileRegexp) = -1;
TOKEN_NARGS(sTJumpIfRegmatch) = -1;
#endif /* MAILER */
setopt('h', 1);
/* argument processing */
progname = argv[0];
if (*progname == '-') {
setopt('c', 1);
zshprofile(LOGIN_SCRIPT);
}
loadit = errflag = 0;
zoptind = 1; /* Not to be influenced by previous zgetopt()'s. */
while (1) {
c = zgetopt(argc, (char**)argv, "CGIJLMOPRSYc:l:isaefhkntuvx");
if (c == EOF)
break;
switch (c) {
case 'O': /* optimize */
if (isset(c))
setopt('V', 1); /* print optimizer output */
setopt(c, 1);
break;
case 'C': /* coder (what the S/SL emits) */
if (isset(c)) {
setopt('W', 1); /* print optimizer output */
setopt(c, 0); /* turn off ugly output */
} else
setopt(c, 1);
break;
case 'G': /* conscell GC debugging */
newcell_gc_interval = 1;
D_conscell = 1;
case 'R': /* runtime I/O */
case 'I': /* interpreter (runtime interpretation) */
case 'J': /* interpreter (runtime interpretation) */
case 'Y': /* just open the runiofp stream */
setopt(c, 1);
if (runiofp == stdout) {
io = open("/dev/tty", O_WRONLY, 0);
dup2(io, 60);
close(io);
runiofp = fdopen(60 /* out of the way */, "w");
}
break;
/* these are the normal shell-external flags */
case 'c': /* run the command given as an argument */
if (isset(c)) {
fprintf(stderr,
"%s: illegal duplicate option '%c'\n",
progname, c);
++errflag;
break;
}
setopt(c, 1);
zshprofile(zoptarg);
break;
case 'l': /* load the precompiled script, ignore optarg */
case 'i': /* interactive shell */
case 's': /* read commands from stdin */
/* these are the shell-internal flags */
case 'a': /* automatically export new/changed variables */
case 'e': /* exit on error exit status of any command */
case 'f': /* disable filename generation (no globbing) */
case 'h': /* hash program locations */
case 'k': /* place all keyword arguments in environment */
case 'n': /* read commands but do not execute them */
case 't': /* read and execute one command only */
case 'u': /* unset variables are error on substitution */
case 'v': /* print shell input lines as they are read */
case 'x': /* print commands as they are executed */
/* these are the miscellaneous debugging flags we're fond of */
case 'L': /* lexer (char-by-char input) */
case 'M': /* memory statistics */
case 'P': /* parser (S/SL tracing) */
case 'S': /* scanner (assembling tokens) */
setopt(c, 1);
break;
default:
++errflag;
}
}
if (errflag) {
fprintf(stderr, USAGE, argv[0]);
exit(1);
}
if (!isset('s')) {
if (zoptind == argc) {
/* read commands from stdin */
setopt('s', 1);
} else if ((io = open(argv[zoptind], O_RDONLY, 0)) < 0) {
fprintf(stderr, "%s: open(\"%s\"): %s\n",
progname, argv[zoptind],
strerror(errno));
exit(1);
} else if (io != 0) {
dup2(io, 0);
close(io);
}
}
if (!isset('i') && isatty(0) && isatty(2))
setopt('i', 1);
if (isset('i')) {
SIGNAL_IGNORE(SIGTERM);
SIGNAL_HANDLE(SIGINT, trap_handler);
}
avcmd.argv = NULL;
staticprot(& avcmd.argv); /* LispGC */
staticprot(& commandline); /* LispGC */
staticprot(& envarlist); /* LispGC */
avcmd.argv = s_listify(argc-zoptind, &argv[zoptind]);
if (isset('s')) {
conscell *d = NULL;
GCVARS1;
GCPRO1(d);
d = conststring(progname,strlen(progname));
s_push(d, avcmd.argv);
UNGCPRO1;
}
v_envinit();
v_set(PS2, DEFAULT_PS2);
if (uid == 0) {
v_set(PS1, DEFAULT_ROOT_PS1);
} else {
v_set(PS1, DEFAULT_PS1);
}
path_flush();
mail_flush();
mail_intvl();
glob_init();
/* we don't inherit IFS, enforced in envinit() */
v_set(IFS, DEFAULT_IFS);
if (isset('l') && argv[zoptind] != NULL)
exit(leaux(-1, argv[zoptind], (struct stat *)NULL));
stickymem = oval;
}
/* cleanup function, only called if pedantic about freeing allocated memory */
void
zshfree()
{
sp_scan(xundefun, (struct spblk *)NULL, spt_funclist);
sp_null(spt_funclist);
/* s_free_tree(envarlist); */
envarlist = NULL;
}
/* return no. of characters left to read from *cpp */
int
zshinput(contd, cpp, moredata, bobufp, eobufp)
int contd; /* 0 for PS1, 1 for PS2 */
char **cpp; /* will point at input characters */
int *moredata; /* set to indicate if there is more to read */
char **bobufp, **eobufp; /* range of valid data for error msgs */
{
int n;
char *cp;
static char buf[BUFSIZ];
if (sprung)
trapped();
if (isset('c') && commandline == NULL) {
++saweof;
return 0;
}
if (commandline) {
*bobufp = (char *)commandline->string;
*eobufp = (char *)commandline->string
+ strlen((char *)commandline->string);
cp = tmalloc(*eobufp - *bobufp + 1);
memcpy(cp, *bobufp, *eobufp - *bobufp + 1);
*eobufp = cp + (*eobufp - *bobufp);
*bobufp = *cpp = cp;
commandline = s_popstack(commandline);
*moredata = (commandline != NULL);
if (isset('v'))
fwrite(*bobufp, 1, *eobufp - *bobufp, stdout);
return *eobufp - *bobufp;
}
*moredata = 0;
if (interrupted)
interrupted = 0;
again:
if (isset('i')) {
if (contd) prompt2_print();
else {
mail_check();
prompt_print();
}
fflush(stdout);
}
if ((n = read(0, buf, sizeof buf)) <= 0) {
if (n == -1 && errno == EINTR) {
putchar('\n');
if (!contd) {
interrupted = 0;
if (sprung)
trapped();
goto again;
} else
return 0;
}
++saweof;
return 0;
}
*bobufp = *cpp = buf;
*eobufp = buf + n;
if (n == sizeof buf)
*moredata = 1;
if (isset('v'))
fwrite(*bobufp, 1, n, stdout);
return n;
}
syntax highlighted by Code2HTML, v. 0.9.1