V7M/src/cmd/shutdown.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Unix/v7m gracefull system shutdown - shutdown.c
 * Fred Canter 9/25/81
 *
 * Thanks to Jerry Brenner for 90% of this program.
 */
#include <stdio.h>
#include <signal.h>
#include <a.out.h>
#include <core.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/tty.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <utmp.h>

struct nlist nl[] = {
	{ "_proc" },
	{ "_swapdev" },
	{ "_nproc" },
	{ "_swplo" },
	{ "" },
};

struct	proc mproc;
struct	utmp	utmp[50];

struct	user u;
int	chkpid;
int	retcode=1;
char	*tptr;
long	lseek();
char	*strcat();
char	*strcpy();
char	*strcmp();
char	*strncmp();
char	*ttynam;
char	*ttyname();
int	mem;
int	swmem;
int	swap;
daddr_t	swplo;
int	nproc;

int	ndev;
struct devl {
	char	dname[DIRSIZ];
	dev_t	dev;
} devl[256];

char	*coref;
int	deltim;
char	umntmsg[]	= {"/etc/unmount"};
char	cnsle[]	= {"/dev/console"};
char	lokfil[]  = {"/etc/sdloglock"};

main(argc, argv)
char **argv;
{
	int	stop();
	int i;
	char *ap, c;
	int uid, puid, pid, pgid;
	int incnt;
	char inbuf[80];
	extern int deltim;

	signal(SIGINT, stop);
	chdir ("/etc");
	ttynam = ttyname(0);
	if (strcmp(cnsle, ttynam))
	{
		printf("\nShutdown can only be run from the console device\n");
		exit();
	}
	if (argc>1)
	{
		ap = argv[1];
		deltim = atoi(ap);
	}
	else
	{
		printf("\nHow many minutes until shutdown [1-99] ? ");
		for (incnt = 0; c != '\n' ; ++incnt)
		{
			c = getchar();
			inbuf[incnt] = c;
		}
		deltim = atoi(inbuf);
	}
	if (deltim > 99 || deltim < 0) {
		printf("\nShutdown time out of range\n");
		exit(0);
		}
	creat(&lokfil, 0);
	for (;deltim >= 0; --deltim)
	{
		sndall();
		if (deltim > 0)
			sleep(60);
	}
	pid = getpid();
	if(chdir("/dev") < 0) {
		fprintf(stderr, "Can't change to /dev\n");
		exit(1);
	}
	nlist(argc>2? argv[2]:"/unix", nl);
	if (nl[0].n_type==0) {
		fprintf(stderr, "No namelist\n");
		exit(1);
	}
	coref = "/dev/mem";
	if ((mem = open(coref, 0)) < 0) {
		fprintf(stderr, "No mem\n");
		exit(1);
	}
	swmem = open(coref, 0);
	/*
	 * read mem to find swap dev.
	 */
	lseek(mem, (long)nl[1].n_value, 0);
	read(mem, (char *)&nl[1].n_value, sizeof(nl[1].n_value));
	/*
	 * Find base of swap
	 */
	lseek(mem, (long)nl[2].n_value, 0);
	read(mem, (char *)&swplo, sizeof(swplo));
	/*
	 * Find number of processes allowed - NPROC
	 */
	lseek(mem, (long)nl[3].n_value, 0);
	read(mem, (char *)&nproc, sizeof(nproc));
	/*
	 * Locate proc table
	 */
	lseek(mem, (long)nl[0].n_value, 0);
	getdev();
	uid = getuid();
	printf("\nKill Process Phase\n\n");
	while(mproc.p_pid != pid)
	{
		read(mem, (char *)&mproc, sizeof mproc);
	}
	pgid = mproc.p_pgrp;
	lseek(mem, (long)nl[0].n_value, 0);
	for (i=0; i<nproc; i++)
	{
		read(mem, (char *)&mproc, sizeof mproc);
		if (mproc.p_stat==0)
			continue;
		if (mproc.p_pgrp==0 && mproc.p_uid==0)
			continue;
		puid = mproc.p_pid;
		if(mproc.p_pgrp==pgid || mproc.p_pgrp==0)
			continue;
		kill (puid, 9);
	}
	printf("******   WAIT FOR SECOND # CHARACTER   ******\n");
	printf("****** DO A SYNC, THEN HALT THE SYSTEM ******\n");
	sync();
	kill(1, 2);
	sync();
}

getdev()
{
#include <sys/stat.h>
	register FILE *df;
	struct stat sbuf;
	struct direct dbuf;

	if ((df = fopen("/dev", "r")) == NULL) {
		fprintf(stderr, "Can't open /dev\n");
		exit(1);
	}
	ndev = 0;
	while (fread((char *)&dbuf, sizeof(dbuf), 1, df) == 1) {
		if(dbuf.d_ino == 0)
			continue;
		if(stat(dbuf.d_name, &sbuf) < 0)
			continue;
		if ((sbuf.st_mode&S_IFMT) != S_IFCHR)
			continue;
		strcpy(devl[ndev].dname, dbuf.d_name);
		devl[ndev].dev = sbuf.st_rdev;
		ndev++;
	}
	fclose(df);
	if ((swap = open("/dev/swap", 0)) < 0) {
		fprintf(stderr, "Can't open /dev/swap\n");
		exit(1);
	}
}



within(adr,lbd,ubd)
char *adr;
long lbd, ubd;
{
	return((unsigned)adr>=lbd && (unsigned)adr<ubd);
}
sndall()
{
	register i;
	register struct utmp *p;
	FILE *f;

	if((f = fopen("/etc/utmp", "r")) == NULL) {
		fprintf(stderr, "Cannot open /etc/utmp\n");
		exit(1);
	}
	fread((char *)utmp, sizeof(struct utmp), 50, f);
	fclose(f);
	f = stdin;
	for(i=0; i<50; i++) {
		p = &utmp[i];
		if(p->ut_name[0] == 0)
			continue;
		sleep(1);
		if((strcmp("root", p->ut_name) == 0)
			&& (strcmp("console", p->ut_line) != 0)) {
			printf("\nShutdown aborted - ");
			printf("user logged in as `root' on %s\n",p->ut_line);
			stop();
			}
		sendmes(p->ut_line);
	}
}

sendmes(tty)
char *tty;
{
	register i;
	char t[50], buf[BUFSIZ];
	FILE *f;
	extern int deltim;

	i = fork();
	if(i == -1) {
		fprintf(stderr, "Try again\n");
		return;
	}
	if(i)
		return;
	strcpy(t, "/dev/");
	strcat(t, tty);

	if((f = fopen(t, "w")) == NULL) {
		fprintf(stderr,"cannot open %s\n", t);
		exit(1);
	}
	setbuf(f, buf);
	fprintf(f, "Broadcast Message ...\n\n");
	if(deltim > 0)
	{
		fprintf(f, "System going down in %d minutes\n\n", deltim);
		fprintf(f, "Please finish up\n\n");
	}
	else
		fprintf(f, "System going down. Bye\n\n");
	exit(0);
}

/*
 * The stop function clears the /etc/sdloglock file
 * if the shutdown is aborted via the interrupt signal.
 * This reenables logins after the sghutdown abort.
 */
stop()
{
	unlink(&lokfil);
	exit(1);
}