/*
 *	El-Cheapo shell
 *
 *	Doesn't do symbol expansion in the right order,
 *	and doesn't do symbol definitions (foo=bar) at all.
 *	But it does get nested command file invocations right.
 *
 *	The expansion problem is that '@' signs (command file
 *	invocation) and parameter substitutions (%n) embedded in
 *	defined symbols do not get expanded.
 *
 *	FDC, 23 Feb 1986
 */

#include <stdio.h>
#include <dict.h>

static nflag = 0;	/* just read commands, don't execute them */
static vflag = 0;	/* echo input lines */
static xflag = 0;	/* echo commands and arguments before executing */

char *getenv ();

main(argc, argv)
int argc;
char *argv[];
{
    char   *a[10];
    register    i = 1;
    register    c;
    register char  *verify;
    void DoLines ();

    if ((verify = getenv ("verify")) != NULL && *verify & 1)
	xflag++;
    a[0] = "shell";
    while (--argc && i < 10) {
	if (**++argv == '-') {
	    while (c = *++(*argv))
		switch (c) {
		    case 'n': 
			nflag++;
			break;
		    case 'x': 
			xflag++;
			break;
		    case 'v': 
			vflag++;
			break;
		    default: {
			    fprintf (stderr, "shell: bad flag %c\n", c);
			    exit (1);
			}
		}
	}
	else
	    a[i++] = *argv;
    }
    while (i < 10)
	a[i++] = NULL;
    DoLines (stdin, a);
}

static void
DoLines(f, a)
FILE *f;
char *a[];
{
    char    buf[256];
    register    len;
    int     LineNo = 0;
    char   *getline ();

    while (1) {
	if (f == stdin) {
	    char   *p = getenv ("prompt");
	    fputs (p ? p : "} ", stdout);
	    if (p)
		free (p);
	}
	if (getline (buf, 256, f, a) == NULL)
	    if (f == stdin)
		continue;
	    else
		return;
	len = strlen (buf);
	if (buf[len - 1] != '\n') {
	    fputs ("Input line", stderr);
	    if (f != stdin)
		fprintf (stderr, "%d", LineNo);
	    fputs (" too long\n", stderr);
	    continue;
	}
	buf[len - 1] = '\0';
	if (!strcmp (buf, "fg") || !strcmp (buf, "!die"))
	    exit (0);
	if (*buf == '!') {
	    if (buf[1] == '!')
		puts (buf + 2);
	    continue;
	}
	if (*buf == '@') {
	    char    fn[32];
	    FILE * f1;
	    char   *a1[10];
	    register    i;
	    register char  *s = buf + 1;
	    register char  *d = fn;

	    for (i = 0; i < 10; i++)
		a1[i] = NULL;
	    for (len = 0; len < 27 && *s && *s > ' '; len++)
		*d++ = *s++;
	    *d = '\0';
	    if (len < 5 || strcmp (d - 4, ".com"))
		strcpy (d, ".com");
	    if ((f1 = fopen (fn, "r")) == NULL) {
		perror (fn);
		continue;
	    }
	    a1[0] = buf + 1;
	    i = 1;
	    while (i < 10 && *s) {
		*s++ = '\0';
		while (*s && *s <= ' ')
		    s++;
		a1[i++] = s;
		while (*s && *s > ' ')
		    s++;
	    }
	    DoLines (f1, a1);
	}
	else
	    if (*buf) {
		if (xflag)
		    fprintf (stderr, "%s\n", buf);
		if (!nflag)
		    system (buf);
	    }
    }
}

static char
*getline(buf, maxlen, f, a)
char *buf;
int maxlen;
FILE *f;
char *a[];
{
    register    i = 0;
    char    tbuf[256];
    register char  *s = tbuf;
    register char  *d = buf;
    register    dlen = 0;

    if (fgets (tbuf, maxlen, f) == NULL)
	return (NULL);
    if (vflag)
	fputs (tbuf, stderr);
    while (dlen < maxlen - 1 && *s) {
	if (*s == '%' && *(s + 1) >= '0' && *(s + 1) <= '9') {
	    char   *ts = a[*++s - '0'];
	    while (*ts && dlen++ < maxlen - 1)
		*d++ = *ts++;
	    s++;
	}
	else {
	    *d++ = *s++;
	    dlen++;
	}
    }
    *d = '\0';
    return buf;
}
