[comp.sources.misc] v16i080: nogetty 1.0, Part01/01

wht@n4hgf.Mt-Park.GA.US (Warren Tucker) (01/17/91)

Submitted-by: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
Posting-number: Volume 16, Issue 80
Archive-name: nogetty/part01

Properly used, nogetty allows one to start execution of a turnkey
application on a particular SCO UNIX V multiscreen from inittab
immediately entry upon a run level.  All login and password
validation are bypassed.

DANGER WILL ROBINSON!  Misuse of this program can compromise the
security of your system.  Carefully read the README and thr source
file header for nogetty.c before use.

#!/bin/sh
# This is nogetty_1.0, a shell archive (shar 3.46)
# made 01/16/1991 19:05 UTC by wht@n4hgf
# Source directory /u1/src/nogetty
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   1181 -rw-r--r-- README
#   2552 -rw-r--r-- dumpwtmp.c
#  14014 -rw-r--r-- nogetty.c
#
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
	echo 'x - skipping README (File already exists)'
else
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XNOGETTY 1.00 - wht@n4hgf.Mt-Park.GA.US - Mon Jan 14 07:28:00 EST 1991
X---------------------------------------------------------------------
X
XProperly used, nogetty allows one to start execution of a turnkey
Xapplication on a particular SCO UNIX V multiscreen from inittab
Ximmediately entry upon a run level.  All login and password
Xvalidation are bypassed.
X
XDANGER WILL ROBINSON!  Misuse of this program can compromise the
Xsecurity of your system.  Carefully read the source file header
Xfor nogetty.c before use.
X
XAlso provided is dumpwtmp.c, a program which displays utmp
Xand wtmp in exhaustive detail.
X
XI almost always provide a Makefile.  But not this time.  While
Xyou are typing, think again whether this is a program you want
Xto use or not.
X
XTo compile,
Xcc -O -o nogetty nogetty.c
Xcc -O -o dumpwtmp dumpwtmp.c
X
X(oh all right, 'make nogetty dumpwtmp' will probably do it too)
X
XTo install:
Xmv nogetty /etc/nogetty
Xchown bin /etc/getty
Xchgrp bin /etc/getty
Xchmod 100 /etc/nogetty
X
XThen, an inittab entry like:
X
Xc05:2:respawn:/etc/nogetty turnkey tty05 bake_turkey
X
Xwill continously respawn a process on tty05 with username 'turnkey'
Xand run program or shell script 'bake_turkey'
X
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 1181 -eq "$Wc_c" ||
	echo 'README: original size 1181, current size' "$Wc_c"
fi
# ============= dumpwtmp.c ==============
if test -f 'dumpwtmp.c' -a X"$1" != X"-c"; then
	echo 'x - skipping dumpwtmp.c (File already exists)'
else
echo 'x - extracting dumpwtmp.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dumpwtmp.c' &&
X/* CHK=0xC327 */
X/*+-----------------------------------------------------------------------
X	dumpwtmp.c -- dump /usr/adm/wtmp and /etc/utmp
X
X  Defined functions:
X	display_utmp(ut)
X	main(argc,argv,envp)
X	ut_type_text(ut_type)
X
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-14-1991-05:01-wht@n4hgf-beef up */
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <utmp.h>
X
Xextern char *ctime();
X
X/*+-------------------------------------------------------------------------
X	ut_type_text(ut_type)
X--------------------------------------------------------------------------*/
Xchar *
Xut_type_text(ut_type)
Xushort ut_type;
X{
Xstatic char errant[32];
X
X	switch(ut_type)
X	{
X		case EMPTY: return("EMPTY");
X		case RUN_LVL: return("RUN_LVL");
X		case BOOT_TIME: return("BOOT_TIME");
X		case OLD_TIME: return("OLD_TIME");
X		case NEW_TIME: return("NEW_TIME");
X		case INIT_PROCESS: return("INIT_PROCESS");
X		case LOGIN_PROCESS: return("LOGIN_PROCESS");
X		case USER_PROCESS: return("USER_PROCESS");
X		case DEAD_PROCESS: return("DEAD_PROCESS");
X		case ACCOUNTING: return("ACCOUNTING");
X		default:
X			sprintf(errant,"type=%u",ut_type);
X			return(errant);
X	}
X
X}	/* end of ut_type_text */
X
X/*+-------------------------------------------------------------------------
X	display_utmp(ut)
X--------------------------------------------------------------------------*/
Xdisplay_utmp(ut)
Xstruct utmp *ut;
X{
X	printf("%-8.8s ",ut->ut_user);		/* User login name */
X	printf("%-4.4s ",ut->ut_id); 		/* /etc/lines id(usually line #) */
X	printf("%-12.12s ",ut->ut_line);	/* device name (console, lnxx) */
X	printf("%05d ",ut->ut_pid);			/* process id */
X	printf("%s\n",ut_type_text(ut->ut_type));	/* type of entry */
X	printf("         term=%03d  exit=%03d time=%s",
X		ut->ut_exit.e_termination,ut->ut_exit.e_exit,
X		ctime(&ut->ut_time));
X
X}	/* end of display_utmp */
X
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xstruct utmp ut;
Xregister int ufd;
Xint local = 0;
Xint all = 0;
X
X	printf("------------ %s -------------------------\n",UTMP_FILE);
X	if((ufd = open(UTMP_FILE,O_RDONLY,755)) < 0)
X	{
X		perror(UTMP_FILE);
X		exit(1);
X	}
X	while(read(ufd,&ut,sizeof(ut)) > 0)
X		display_utmp(&ut);
X	close(ufd);
X
X	printf("------------ %s -------------------------\n",WTMP_FILE);
X	if((ufd = open(WTMP_FILE,O_RDONLY,755)) < 0)
X	{
X		perror(WTMP_FILE);
X		exit(1);
X	}
X	while(read(ufd,&ut,sizeof(ut)) > 0)
X		display_utmp(&ut);
X	close(ufd);
X
X	exit(0);
X}
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of dumpwtmp.c */
SHAR_EOF
chmod 0644 dumpwtmp.c ||
echo 'restore of dumpwtmp.c failed'
Wc_c="`wc -c < 'dumpwtmp.c'`"
test 2552 -eq "$Wc_c" ||
	echo 'dumpwtmp.c: original size 2552, current size' "$Wc_c"
fi
# ============= nogetty.c ==============
if test -f 'nogetty.c' -a X"$1" != X"-c"; then
	echo 'x - skipping nogetty.c (File already exists)'
else
echo 'x - extracting nogetty.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'nogetty.c' &&
X/* CHK=0xB514 */
Xchar *revision = "@(#)nogetty 1.00 wht@n4hgf";
X/*+-------------------------------------------------------------------------
X	nogetty.c - bypass getty (nasty) on SCO and perhaps other S5R3
X	wht@n4hgf.Mt-Park.GA.US
X
XProperly used, nogetty allows one to start execution of a turnkey
Xapplication on a particular MULTISCREEN (see below) from inittab
Ximmediately entry upon a run level.  All login and password
Xvalidation are bypassed.
X
XRun as root:
X/etc/nogetty usrname tty [command [arg ...]]
X
XDANGER WILL ROBINSON!
X----------------------
XBecause this violates Rules and Regulations of the C2 Brown Shirt
XPreservation League, I feel I must deviate from my usual lack of
Xverbiage.  The is no 'F' TCB classification, but this program
Xwarrants creation of one.
X
X1.  Misuse of this program can compromise the security of your system.
X
X2.  Making this program setuid to root WILL completely and fully
X    and probably PERMANENTLY compromise the slightest precepts of
X    security on your system (System->Configure->Security->Drown).
X
X3.  No attempt is made to set the LUID. The ultimate ramifications
X    are unknown, but the immediate effects are to bypass much of
X    the C2 ParanoidWare.
X
X4.  Not only is there no warranty or guarantee on this software,
X    but I don't want to even hear any of the horror stories possibly
X    resulting from the casual use of this software.
X
XNOT ME! I DIDN'T DO IT
X----------------------
XNogetty is provided on an as-is basis.  In no account will Warren Tucker
Xor any other individual or entity be held accountable or liable for
Xany direct or indirect consequences arising from the use of this
Xsoftware.
X
XTTY INITIALIZATION
X------------------
X1. ISIG is purposefully omitted from the initial tty setup so that
XRUBOUT (SIGINT) processing may not abort the started application.
XYou may wish to reenable it by use of 'stty isig'. Be aware that
Xsome applications when started may of their own accord enable
XSIGINT processing either directly or through the invocation of 
Xother processes.
X
X2. A 'mesg n' is simulated by chmod 0600 of the terminal device.
X
X3. The tty is always initialized to 9600 baud, no parity, one stop bit.
X
X4. Otherwise, the tty is initialized pretty much as getty/login would.
X
XSUITABLE APPLICATIONS
X---------------------
XApplications started with nogetty that fork other processes
Xshould receive particular attention with respect to security.
XThe ability of a child process to executing a shell is of obvious
Xconcern, but bear in mind that starting programs like vi can be a
Xproblem since THEY have a shell capability.  Of course, since you
Xare the god of your system, it is up to YOU to decide what is
Xbest for your child and behave as you feel best.
X
XAPPLICATION ENVIRONMENT
X-----------------------
XThe preferred (/etc/passwd) shell for <username> is started as
Xa login shell (i.e., .login will be executed if the shell is csh).
X
XTo allow for login processing to differentiate between normal
Xand nogetty startups, nogetty adds an environment variable
X   NOGETTY=/dev/ttyxx
X
XThe single <command> is executed, whereupon nogetty exits.
X
XUTMP, INITTAB, WHO, ENABLE/DISABLE
X----------------------------------
XUtmp and wtmp are properly updated per the ad-hoc SCO usage of
Xutmp's ut_id.  The ut_id field of the utmp entry for a *multiscreen*
Xis comprised of a 'c' followed by the last two (numeric) characters
Xof the tty id.  Use of nogetty to start an application on a
Xnon-multiscreen will require analysis of the ut_id format and
Xuse of the '-i' switch.
X
XIf you handle this little bit, then you should be able to
Xuse all the standard features of inittab, who and enable/disable.
XOtherwise, erroneous utmp entries will be generated, adversely
Xaffecting these control and status functions.
X
XLOG FILE: /etc/nogetty.log
X--------------------------
XError logging is done in /etc/nogetty.log.  It grows forever unless
Xyou do something about it.
X
X  Defined functions:
X	add_to_argv(arg)
X	add_to_env(env)
X	adjust_env(buf)
X	fatal_news(buf,detail)
X	get_TZ_HZ()
X	main(argc,argv)
X	smart_fork()
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:01-14-1991-01:19-wht@n4hgf-creation */
X
X#include <stdio.h>
X#undef NULL
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/wait.h>
X#include <sys/param.h>
X#include <sys/errno.h>
X#include <ctype.h>
X#include <signal.h>
X#include <termio.h>
X#include <string.h>
X#include <memory.h>
X#include <malloc.h>
X#include <fcntl.h>
X#include <time.h>
X#include <pwd.h>
X#include <utmp.h>
X
X#define MAX_NEWENV 64
Xchar *new_environ[MAX_NEWENV] = {(char *)0};
Xchar **new_environ_add_ptr = new_environ;
Xint new_environ_count = 0;
X
X#define MAX_NEWARGV (NCARGS)
Xchar new_argv[MAX_NEWARGV] = {0};
Xint new_argv_count = 0;
X
Xchar *ttydev = (char *)0;
Xchar *usrname = (char *)0;
Xchar *cmd = (char *)0;
X
X/*+-------------------------------------------------------------------------
X	fatal_news(buf,detail) - write fatal error message to log file and die
X
Xsleep for 10 secs so a repeating error won't make init rattle the
Xworld respawning us
X--------------------------------------------------------------------------*/
Xvoid
Xfatal_news(buf,detail)
Xchar *buf;
Xchar *detail;
X{
X	int fd = open("/etc/nogetty.log",O_CREAT|O_WRONLY|O_CREAT,0644);
X
X	if(fd >= 0)
X	{
X		write(fd,buf,strlen(buf));
X		if(detail && *detail && (strlen(detail) < 128))
X		{
X			write(fd," [",2);
X			write(fd,detail,strlen(detail));
X			write(fd,"]",1);
X		}
X		write(fd,"\n",1);
X		close(fd);
X	}
X
X	sleep(10);
X	_exit(255);
X
X}	/* end of fatal_news */
X
X/*+-------------------------------------------------------------------------
X	add_to_env(env)
X--------------------------------------------------------------------------*/
Xvoid
Xadd_to_env(env)
Xchar *env;
X{
X	char *item = malloc(strlen(env) + 1);
X
X	if(!item)
X		fatal_news("nogetty: memory alloc failed",ttydev);
X	strcpy(item,env);
X	if(new_environ_count >= (MAX_NEWENV - 1))
X		fatal_news("nogetty: too many environment variables",ttydev);
X	*new_environ_add_ptr++ = item;
X	new_environ_count++;
X
X}	/* end of add_to_env */
X
X/*+-------------------------------------------------------------------------
X	adjust_env(buf) - get rid of coments or space/tab
X--------------------------------------------------------------------------*/
Xvoid
Xadjust_env(buf)
Xchar *buf;
X{
X	char *cptr;
X
X	if(cptr = strchr(buf,'#'))
X		*cptr = 0;
X	if(cptr = strchr(buf,' '))
X		*cptr = 0;
X	if(cptr = strchr(buf,'\t'))
X		*cptr = 0;
X
X}	/* end of adjust_env */
X
X/*+-------------------------------------------------------------------------
X	get_TZ_HZ() - get TZ and HZ from /etc/TIMEZONE
X
Xfailing to find either, fake it somehow
X--------------------------------------------------------------------------*/
Xvoid
Xget_TZ_HZ()
X{
X	int itmp;
X	char buf[128];
X	char *cptr;
X	FILE *fp = fopen("/etc/TIMEZONE","r");
X	int found_tz = 0;
X	int found_hz = 0;
X	char *getenv();
X
X	if(fp)
X	{
X		while(fgets(buf,sizeof(buf),fp))
X		{
X			if((itmp = strlen(buf)) && (buf[itmp - 1] == '\n'))
X				buf[itmp - 1] = 0;
X			if(!strncmp(buf,"HZ=",3))
X			{
X				adjust_env(buf);
X				add_to_env(buf);
X				found_hz = 1;
X			}
X			else if(!strncmp(buf,"TZ=",3))
X			{
X				adjust_env(buf);
X				add_to_env(buf);
X				found_tz = 1;
X			}
X		}
X		fclose(fp);
X	}
X
X	if(!found_tz)
X	{
X		if(cptr = getenv("TZ"))
X		{
X			sprintf(buf,"TZ=%s",cptr);
X			add_to_env(buf);
X		}
X		else
X			add_to_env("TZ=EST5EDT");
X	}
X	if(!found_hz)
X	{
X		if(cptr = getenv("HZ"))
X		{
X			sprintf(buf,"HZ=%s",cptr);
X			add_to_env(buf);
X		}
X		else
X		{
X			sprintf(buf,"HZ=%d",HZ);
X			add_to_env(buf);
X		}
X	}
X
X}	/* end of get_TZ_HZ */
X
X/*+-------------------------------------------------------------------------
X	add_to_argv(arg)
X--------------------------------------------------------------------------*/
Xvoid
Xadd_to_argv(arg)
Xchar *arg;
X{
Xregister len = strlen(arg);
X
X	if(new_argv_count + len + 1 >= sizeof(new_argv))
X		fatal_news("nogetty: argv too long",ttydev);
X	if(new_argv_count)
X	{
X		strcat(new_argv," ");
X		new_argv_count++;
X	}
X	strcat(new_argv,arg);
X	new_argv_count += len;
X
X}	/* end of add_to_argv */
X
X/*+-------------------------------------------------------------------------
X	smart_fork()
X--------------------------------------------------------------------------*/
Xint
Xsmart_fork()
X{
X	register int count = 5;
X	register int pid;
X
X	while(count--)
X	{
X		if((pid = fork()) >= 0)
X			return(pid);
X		if(count)
X			sleep(2);
X	}
X	return(-1);
X}	/* end of smart_fork */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv)
X--------------------------------------------------------------------------*/
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X	int itmp;
X	int fd0,fd1,fd2,fdwtmp;
X	int child;
X	int wait_status;
X	struct termio tio;
X	struct stat st;
X	struct passwd *pw;
X	struct utmp ut;
X	struct utmp *utptr;
X	char s128[128];
X	char ttydev2[64];
X	char *cptr;
X	char *ut_id_override = (char *)0;
X	int errflg = 0;
X	extern char *optarg;
X	extern int optind;
X
X	while((itmp = getopt(argc,argv,"i:")) != -1)
X	{
X		switch(itmp)
X		{
X			case 'i':
X				ut_id_override = optarg;
X				break;
X			case '?':
X				errflg++;
X		}
X	}
X	if(errflg || ((argc - optind) < 2))
X	{
X		fatal_news("nogetty: invalid invocation","usage");
X		exit(1);
X	}
X
X	usrname = argv[optind];
X	ttydev = argv[optind + 1];
X	cmd = argv[optind + 2];
X	strcpy(ttydev2,"/dev/");
X	strcat(ttydev2,ttydev);
X
X	pw = getpwnam(usrname);
X	endpwent();
X	if(!pw)
X		fatal_news("nogetty: cannot get password table entry",usrname);
X
X	get_TZ_HZ();
X
X	for(fd0 = 0; fd0 < NOFILES_MAX; fd0++)	/* close every conceivable file */
X		close(fd0);
X
X#ifdef TRY_THIS
X	if((itmp = smart_fork()) < 0)
X		fatal_news("nogetty: cannot fork",ttydev);
X	else if(itmp)		/* parent */
X		_exit(0);
X#endif
X
X	setpgrp();
X
X	if((fd0 = open(ttydev2,O_RDWR,0)) < 0)
X		fatal_news("nogetty: cannot open fd 0",ttydev2);
X	if((fd1 = dup(fd0)) < 0)
X		fatal_news("nogetty: cannot dup fd 1",ttydev2);
X	if((fd2 = dup(fd0)) < 0)
X		fatal_news("nogetty: cannot dup fd 2",ttydev2);
X
X	if(stat(ttydev2,&st))
X		fatal_news("nogetty: cannot stat tty",ttydev2);
X	chown(ttydev2,pw->pw_uid,st.st_gid);
X	chmod(ttydev2,0600);
X
X	ioctl(fd0,TCGETA,(char *)&tio);
X	tio.c_iflag = BRKINT | IGNPAR | ICRNL | IXON | IXANY;
X	tio.c_oflag = OPOST | ONLCR;
X	tio.c_cflag = CREAD | HUPCL | B9600 | CS8 | B9600;
X	tio.c_lflag = ICANON | ECHO | ECHOK;
X	tio.c_cc[VINTR]  = 0x7F;
X	tio.c_cc[VQUIT]  = 0x1C;
X	tio.c_cc[VERASE] = 0x08;
X	tio.c_cc[VKILL]  = 0x15;
X	tio.c_cc[VEOF]   = 0x04;
X	tio.c_cc[VEOL]   = 0x0D;
X	tio.c_cc[VEOL2]  = 0x0A;
X	tio.c_cc[VSWTCH] = 0x00;
X	ioctl(fd0,TCSETA,(char *)&tio);
X
X	/*
X	 * set up utmp entry
X	 */
X
X	setutent();
X	ut.ut_type = LOGIN_PROCESS;
X	if(ut_id_override)
X		strncpy(ut.ut_id,ut_id_override,sizeof(ut.ut_line));
X	else
X	{
X		strcpy(ut.ut_id,"c");
X		strncat(ut.ut_id,ttydev + strlen(ttydev) - 2,sizeof(ut.ut_line) - 1);
X	}
X	strncpy(ut.ut_line,ttydev,sizeof(ut.ut_line));
X	getutid(&ut);
X	ut.ut_type = USER_PROCESS;
X	ut.ut_exit.e_termination = 0;
X	ut.ut_exit.e_exit = 0;
X	strncpy(ut.ut_user,pw->pw_name,sizeof(ut.ut_user));
X	strncpy(ut.ut_line,ttydev,sizeof(ut.ut_line));
X	if(ut_id_override)
X		strncpy(ut.ut_id,ut_id_override,sizeof(ut.ut_line));
X	else
X	{
X		strcpy(ut.ut_id,"c");
X		strncat(ut.ut_id,ttydev + strlen(ttydev) - 2,sizeof(ut.ut_line) - 1);
X	}
X	ut.ut_pid = getpid();
X	time(&ut.ut_time);
X	pututline(&ut);
X	endutent();
X
X	/*
X	 * now be a good camper and update wtmp
X	 */
X
X	if((fdwtmp = open(WTMP_FILE,O_WRONLY | O_APPEND)) >= 0)
X	{
X		strncpy(ut.ut_user,"nogetty",sizeof(ut.ut_user));
X		ut.ut_type = INIT_PROCESS;
X		write(fdwtmp,&ut,sizeof(ut));
X		ut.ut_type = USER_PROCESS;
X		strncpy(ut.ut_user,pw->pw_name,sizeof(ut.ut_user));
X		write(fdwtmp,&ut,sizeof(ut));
X		close(fdwtmp);
X	}
X
X	sprintf(s128,"LOGNAME=%s",pw->pw_name);
X	add_to_env(s128);
X	sprintf(s128,"HOME=%s",pw->pw_dir);
X	add_to_env(s128);
X	sprintf(s128,"PATH=/bin:/usr/bin:/usr/lbin:/usr/dbin:/usr/bin/X11:%s/bin",
X	    pw->pw_dir);
X	add_to_env(s128);
X	sprintf(s128,"MAIL=/usr/spool/mail/%s",pw->pw_name);
X	add_to_env(s128);
X	sprintf(s128,"SHELL=%s",pw->pw_shell);
X	add_to_env(s128);
X	sprintf(s128,"NOGETTY=%s",ttydev);	/* NOGETTY = /dev/ttyxx */
X	add_to_env(s128);
X	add_to_env("TERM=ansi");
X
X	/*
X	 * build new argv
X	 */
X	for(itmp = optind + 2; itmp < argc; itmp++)
X		add_to_argv(argv[itmp]);
X
X	/*
X	 * fork and start fireworks
X	 */
X	if((child = smart_fork()) < 0)
X		fatal_news("nogetty: cannot fork",ttydev);
X	else if(!child)	/* child */
X	{
X		/*
X		 * become the specified user (and his group)
X		 */
X		setgid(pw->pw_gid);
X		setuid(pw->pw_uid);
X		chdir(pw->pw_dir);
X
X		/*
X		 * exec the command line argument in the user's favorite shell
X		 */
X		if(cptr = strrchr(pw->pw_shell,'/'))
X			sprintf(s128,"-%s",cptr + 1);
X		else
X			strcpy(s128,"-");
X		execle(pw->pw_shell,s128,"-v","-c",new_argv,(char *)0,new_environ);
X		fatal_news("nogetty: execute failed",cmd);
X		/* NOTREACHED*/
X	}
X
X	/*
X	 * parent just waits for child (shell term)
X	 */
X	waitpid(child,&wait_status,0);
X
X	/*
X	 * update utmp entry and write new wtmp entry
X	 */
X	setutent();
X	ut.ut_type = USER_PROCESS;
X	if(ut_id_override)
X		strncpy(ut.ut_id,ut_id_override,sizeof(ut.ut_line));
X	else
X	{
X		strcpy(ut.ut_id,"c");
X		strncat(ut.ut_id,ttydev + strlen(ttydev) - 2,sizeof(ut.ut_line) - 1);
X	}
X	utptr = getutid(&ut);
X	if(utptr && (utptr->ut_pid == getpid()))
X	{
X		utptr->ut_type = DEAD_PROCESS;
X		strncpy(ut.ut_user,pw->pw_name,sizeof(ut.ut_user));
X		utptr->ut_exit.e_termination = WTERMSIG(wait_status);
X		utptr->ut_exit.e_exit = WEXITSTATUS(wait_status);
X		time(&utptr->ut_time);
X		pututline(utptr);
X		if((fdwtmp = open(WTMP_FILE,O_WRONLY | O_APPEND)) >= 0)
X		{
X			write(fdwtmp,utptr,sizeof(struct utmp));
X			close(fdwtmp);
X		}
X	}
X	else
X	{
X		ut.ut_type = DEAD_PROCESS;
X		strncpy(ut.ut_user,pw->pw_name,sizeof(ut.ut_user));
X		ut.ut_exit.e_termination = WTERMSIG(wait_status);
X		ut.ut_exit.e_exit = WEXITSTATUS(wait_status);
X		time(&ut.ut_time);
X		if((fdwtmp = open(WTMP_FILE,O_WRONLY | O_APPEND)) >= 0)
X		{
X			write(fdwtmp,utptr,sizeof(struct utmp));
X			close(fdwtmp);
X		}
X	}
X	endutent();
X
X	_exit(0);
X
X}	/* end of main */
X
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of nogetty.c */
SHAR_EOF
chmod 0644 nogetty.c ||
echo 'restore of nogetty.c failed'
Wc_c="`wc -c < 'nogetty.c'`"
test 14014 -eq "$Wc_c" ||
	echo 'nogetty.c: original size 14014, current size' "$Wc_c"
fi
exit 0

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.