DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦eb8295ada⟧ TextFile

    Length: 6301 (0x189d)
    Types: TextFile
    Notes: UNIX file
    Names: »exec3.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »cmd/rsh/exec3.c« 
        └─ ⟦this⟧ »cmd/sh/exec3.c« 

TextFile

/*
 * Bourne shell.
 * Builtin commands.
 */
#include "sh.h"
#include <sys/times.h>
#include <const.h>		/* HZ defined here */
#define HOUR	(60L*60L*HZ)
#define MINUTE	(60L*HZ)
#define SECOND	HZ


extern	s_colon();
extern	s_dot();
extern	s_break();
#define s_continue	s_break
extern	s_cd();
extern	s_eval();
extern	s_exec();
extern	s_exit();
extern	s_export();
extern	s_login();
#define s_newgrp	s_login
extern	s_read();
#define s_readonly	s_export
extern	s_set();
extern	s_shift();
extern	s_times();
extern	s_trap();
extern	s_umask();
extern	s_wait();
#define SNULL	((int (*)())0)

typedef struct {
	int	i_hash;
	char	*i_name;
	int	(*i_func)();
} INLINE;

INLINE inls[] = {
	0,	":",		s_colon,
	0,	".",		s_dot,
	0,	"break",	s_break,
	0,	"continue",	s_continue,
	0,	"cd",		s_cd,
	0,	"eval",		s_eval,
	0,	"exec",		s_exec,
	0,	"exit",		s_exit,
	0,	"export",	s_export,
	0,	"login",	s_login,
	0,	"newgrp",	s_newgrp,
	0,	"read",		s_read,
	0,	"readonly",	s_readonly,
	0,	"set",		s_set,
	0,	"shift",	s_shift,
	0,	"times",	s_times,
	0,	"trap",		s_trap,
	0,	"umask",	s_umask,
	0,	"wait",		s_wait,
	0,	NULL,		SNULL,
};

inline()
{
	register int (*s_func)();
	register INLINE *ip;
	register int ahash;

	if (inls[0].i_hash==0)
		for (ip=inls; ip->i_name!=NULL; ip+=1)
			ip->i_hash = ihash(ip->i_name);
	ahash = ihash(nargv[0]);
	for (ip=inls; ip->i_name!=NULL; ip+=1)
		if (ip->i_hash==ahash && strcmp(nargv[0], ip->i_name)==0)
			break;
	if ((s_func=ip->i_func) == SNULL)
		return (0);
	if (*niovp != NULL && s_func != s_exec) {
		eredir();
		slret = 1;
	} else
		slret = (*s_func)();
	return (1);
}

ihash(cp)
register char *cp;
{
	register int i;
	for (i=0; *cp; i+=*cp++);
	return (i);
}

/*
 * Actual builtin functions.
 */
s_colon()
{
	return (0);
}
s_dot()
{
	if (nargc==2) {
		ffind(NULL);
		if (ffind(vpath, nargv[1], 4))
			return (session(SFILE, duplstr(strt, 0)));
		else {
			ecantfind(nargv[1]);
			return (1);
		}
	} else if (nargc==1)
		return (0);
	syntax();
	return (1);
}
s_break()
{
	register CON *cp;
	register int t;
	register int n;
	int ret;

	ret = nargv[0][0]=='b' ? 2 : 1;
	n = nargc>1 ? atoi(nargv[1]) : 1;
	for (cp = sesp->s_con; cp; cp = cp->c_next) {
		t = cp->c_node->n_type;
		if ((t==NWHILE || t==NFOR || t==NUNTIL) && --n == 0) {
			sesp->s_con = cp;
			longjmp(cp->c_envl, ret);
			break;
		}
		freebuf(cp->c_bpp);
	}
	printe("%s out of bounds", ret==1 ? "Continue" : "Break");
	reset(RBRKCON);
	NOTREACHED;
}
/* s_continue is overlaid with s_break */
s_cd()
{
	register char *cp;

	cp = nargc<2 ? vhome : nargv[1];
	if (chdir(cp) < 0) {
		printe("%s: bad directory", cp);
		return (1);
	}
	return (0);
}
s_eval()
{
	if (nargc>1)
		return (session(SARGV, ++nargv));
	else
		return (0);
}
s_exec()
{
	if (redirect(niovp) < 0) {
		if (nargc>1) {
			exit(1);
			NOTREACHED;
		}
		return (1);
	}
	if (nargc==1)
		return (0);
	if (no1flag)
		cleanup(2, NULL);
	dflttrp(ICMD);
	++nargv;
	--nargc;
	nenvp = envlvar(nenvp);
	flexec();
	exit(1);
	NOTREACHED;
}
s_exit()
{
	if (nargc > 1)
		slret = atoi(nargv[1]);
	reset(RUEXITS);
	NOTREACHED;
}
s_export()
{
	register int flag;
	register char **varv;

	flag = nargv[0][0]=='e' ? VEXP : VRDO;
	if (nargc < 2)
		tellvar(flag);
	else
		for (varv=++nargv; *varv; )
			if (namevar(*varv))
				flagvar(*varv++, flag);
			else
				eillvar(*varv++);
	return (0);
}
s_login()
{
	register char *cmd;

	cmd = nargv[0][0]=='l' ? "/bin/login" : "/bin/newgrp";
	execve(cmd, nargv, envlvar(nenvp));
	ecantfind(cmd);
	return (1);
}
/* s_newgrp is overlaid with s_login */
s_read()
{
	SES s;
	register int n, c;
	register char **vp;
	int eol;

	s.s_type = SSTR;
	s.s_flag = 0;
	s.s_ifp = stdin;
	s.s_next = sesp;
	sesp = &s;
	for (eol=0, vp=++nargv, n=--nargc; n; n-=1, vp+=1) {
		if (n==1 && ! eol) {
			strp = strt;
			c = collect('\n', 2);
			if (c == '\n')
				--strp;
			*strp = '\0';
		} else if (! eol)
			c = yylex();
		else
			*strt = '\0';
		if (namevar(*vp))
			assnvar(*vp, duplstr(strt, 0));
		else
			eillvar(*vp);
		eol = c=='\n' || c==EOF;
	}
	sesp = s.s_next;
	return (c==EOF);
}
/* s_readonly overlaid with s_export */
s_set()
{
	if (nargc < 2) {
		tellvar(0);
		return (0);
	}
	return (set(nargc, nargv, 0));
}
s_shift()
{
	register int n;

	n = nargc > 1 ? atoi(nargv[1]) : 1;
	while (n > 0 && sargc > 0) {
		n -= 1;
		sargc -= 1;
		sargp += 1;
	}
	return (n!=0);
}
s_times()
{
	struct tbuffer tb;

	times(&tb);
	ptime(tb.tb_cutime);
	ptime(tb.tb_cstime);
	prints("\n");
	return (0);
}
s_trap()
{
	register char **vp;
	register char *cp;
	register int err;

	err = 0;
	if (nargc==1)
		return (telltrp());
	vp = ++nargv;
	cp = *vp;
	if (class(cp[0], MDIGI)
	 && (cp[1]=='\0' || (class(cp[1], MDIGI) && cp[2]=='\0')))
		cp = NULL;
	else
		++vp;
	while (*vp) {
		if (class(vp[0][0], MDIGI))
			err |= setstrp(atoi(*vp++), cp);
		else {
			printe("Bad trap: %s", *vp++);
			err |= 1;
		}
	}
	return (err);
}
s_umask()
{
	if (nargc < 2)
		prints("%03o\n", ufmask);
	else
		umask(ufmask = atoi(nargv[1]));
	return (0);
}
s_wait()
{
	register int f;

	f = (nargc > 1) ? atoi(nargv[1]) : 0;
	if (f > 0)
		f = -f;
	waitc(f);
	return (slret);
}

/*
 * The set command.  This is also called from `main' to set
 * options from the command line.  In this case `flag' is
 * set.
 */
set(argc, argv, flag)
register char *argv[];
{
	int n;
	register char *cp;

	if (flag) {
		cflag = 0;
		iflag = 0;
		sflag = 0;
	}
	n = 0;
	if (argc > 0)
		n = 1;
	if (argc>1 && argv[1][0]=='-') {
		register char *fp;

		n++;
		for (cp = &argv[1][1]; *cp; cp++) {
			if ((fp=index(shfnams, *cp)) == NULL
			 || (fp+=shflags-shfnams) == NULL
			 || (fp != &lgnflag && fp > &xflag && flag == 0))
				printe("-%c: Bad option", *cp);
			else if (fp != &lgnflag)
				*fp = *cp;
		}
		if (cp == &argv[1][1]) {
			vflag = 0;
			xflag = 0;
		}
		if (flag == 0 && argc == 2)
			return (errflag);
	}
	if (errflag)
		return (1);
	if (sargv != NULL) {
		vfree(sargv);
	}
	sargv = vdupl(argv);
	sargc = argc - n;
	sargp = sargv + n;
	return (0);
}

/*
 * print the time as XmX.Xs
 * as fixed by Randall.
 */
ptime(t)
long t;
{
	register int ticks, tenths, seconds;

	prints("%Dm", t/MINUTE);
	ticks = t%MINUTE;
	seconds = ticks/SECOND;
	tenths = (ticks%SECOND + SECOND/20)/(SECOND/10);
	if (tenths == 10) {
		tenths = 0;
		seconds++;
	}
	prints("%d.%ds ", seconds, tenths);
}