[net.sources] on.c -- toggle gettys

CSvax:cak (10/09/82)

/*
 *	on/off -- enable/disable ttys for login
 *
 *	usage -- on [-n] [-f] [ttyname]
 *
 *	on with a ttyname will enable that tty for login, by modifying
 *	/etc/ttys, and signalling /etc/init.
 *
 *	off will turn the tty off. If someone is logged in, as shown in
 *	/etc/utmp, /etc/ttys will be changed, but /etc/init will
 *	not be signalled, allowing the user to finish. (A message
 *	to that effect is printed.) The -f flag will force a logoff.
 *
 *	-n in either case will cause on/off to modify /etc/ttys, but
 *	not signal /etc/init.
 *
 *	in all cases, ttyname is the full device name, stripped of the
 *	leading /dev/.
 *	
 *	Invoking the program with no arguments signals /etc/init.
 *
 *	The same object performs both functions, thus there should be
 * 	two links to it. The function is determined by the last
 *	character of argv[0].
 *
 *	Chris Kent, University of Cincinnati, 9/13/81
 */

#include	<utmp.h>
#include	<stdio.h>
#include	<signal.h>

#define	INITPID		1		/* the pid assumed for /etc/init */
#define	STARTSIG	SIGHUP		/* signal to make /etc/init restart */
#define	UTMP		"/etc/utmp"	/* record of who is on */
#define	TTYS		"/etc/ttys"	/* the ttys file */
#define	TEMPLATE	"/tmp/onXXXXXX"	/* template for temporary file */

#define	ENABLED		1
#define DISABLED	0
#define	ON		1
#define	OFF		0
#define	OFFMODE		0666		/* mode to reset tty to */

struct	utmp	u_entry;

main(argc, argv)
char *argv[];
{
	register FILE		*ufd, *ttysfd, *tempfd;
	char			*ttyname;
	char			*tempname;
	char			*mktemp(), ctime();
	short			onoff;
	short			force, nosig;
	short			turkey;
	short			found;
	char			name[9];
	char			combuf[128];
	char			login, getty;
	
	if(argc > 3){
		fprintf(stderr, "usage: %s [-n] [-f] [ttyname]\n", argv[0]);
		exit(-1);
	}

	if(argc == 1){
		kill(INITPID, STARTSIG);
		exit(0);
	}

	if(argv[0][strlen(argv[0])-1] == 'f')
		onoff = OFF;
	else
		onoff = ON;

	while(--argc)
		switch((*++argv)[0]){
		case '-':
			switch(argv[0][1]){
			case 'n':
				nosig = 1;
				break;
			case 'f':
				force = 1;
				break;
			default:
				fprintf(stderr, "bad flag %s\n", *argv);
			}
			break;
		default:
			ttyname = argv[0];
		}
	ufd = fopen(UTMP, "r");
	ttysfd = fopen(TTYS, "r");
	tempname = mktemp(TEMPLATE);
	if((tempfd = fopen(tempname, "w")) == NULL){
		fprintf(stderr, "Can't create temp file");
		exit(-2);
	}

	/* 
	 * read in TTYS, modify the proper record, copy to temp file
	 */

	found = 0;
	while(fscanf(ttysfd, "%c%c%s\n", &login, &getty, name) != EOF){
		if(strncmp(name, ttyname, 8)){
			fprintf(tempfd, "%c%c%s\n", login, getty, name);
			continue;
		}
		found = 1;
		fprintf(tempfd, "%1d%c%s\n", onoff, getty, name);
	}

	if(!found){
		fprintf(stderr, "No line in %s for %s\n", TTYS, ttyname);
		unlink(tempname);
		exit(-1);
	}

	fflush(tempfd);

	/* 
	 * copy new version into place
	 */

	tempfd = fopen(tempname, "r");
	ttysfd = fopen(TTYS, "w");

	if(ttysfd == NULL){
		fprintf(stderr, "Can't rewrite %s: ", TTYS);
		perror("");
		unlink(tempname);
		exit(-1);
	}

	while(fgets(combuf, sizeof(combuf), tempfd) != NULL)
		fputs(combuf, ttysfd);
	
	fclose(ttysfd);
	fclose(tempfd);

	unlink(tempname);

	/*
	 * see if someone is logged in
	 */

	turkey = 0;

	while(fread(&u_entry, sizeof (struct utmp), 1, ufd) != NULL)
		if(!strncmp(u_entry.ut_line, ttyname, 8) && *u_entry.ut_name){
			fprintf(stderr, "%s logged in on /dev/%s since %s",
			     u_entry.ut_name, ttyname, ctime(&u_entry.ut_time));
			turkey = 1;
		}
	
	/*
	 * restart init
	 */

	if((force || !turkey) && !nosig)
		kill(INITPID, STARTSIG);

	if(onoff == OFF){
		sprintf(combuf, "/dev/%s", ttyname);
		chmod(combuf, OFFMODE);
	}

	exit(turkey);
}