[net.sources] gone.c found

lizard@nbires.UUCP (LisaLynn Turboff) (02/13/84)

Are you, yes you, looking for the source for gone.c?  Well, as Lyle
McElhaney from Denelcor pointed out to me, the source for gone.c is
on the Rand Corp Distribution tape.  Here it is.  Thanks to everybody
who responded kindly.  Foo on those who didn't.

/*
/*      this program ignores its arguments, and won't do ANYTHING
/*      until you type your password.  All signals are ignored.
/*
/*      If someone else wants to use your terminal while you are away,
/*      he'll have to hang it up and start over.  This would be hard
/*      to fix and would require gone to be setuid root, because you
/*      would have to spawn a login, then put back your userid into
/*      /etc/wtmp.  Also, while he is logged in, your `gone' disappears
/*      from the output of `w'.  FURTHERmore, you have to remember
/*      that when he logs off, you are back in the loop waiting for
/*      your password so you can continue...
/*
/*      Dave Yost, Rand, Aug 27, 1981
/**/

#include <whoami.h>
#include <stdio.h>
#include <pwd.h>
#include <sgtty.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>

#define Block
/* typedef int void;    /* if old C compiler */

#define MAXALARM ((unsigned int) 65535)

extern char *crypt ();
extern char *strcpy ();
extern char *malloc ();
char   *xgetpass ();
int     setpwent ();
char   *r1bindex ();
struct  passwd *whoisthis ();
extern char *strsav ();

main(argc, argv)
int argc;
char **argv;
{
	char *fullname;
	struct  passwd *pwd;

	if (argc <= 1) {
		fprintf (stderr,
			 "Say something about how long you will be gone and where.\n");
		exit (1);
	}

	if (NULL == (pwd = whoisthis ())) {
		fprintf (stderr, "Who are you?\n");
		exit (1);
	}

	if (*pwd->pw_passwd == '\0') {
		fprintf (stderr, "Your password is null\n");
		exit (1);
	}

	fullname = r1bindex (pwd->pw_gecos, ';');
	printf ("This terminal is in use by %s (%s) on %s\n",
		pwd->pw_name, fullname, sysname);
	printf ("If you really must use it, you will have to turn it off and on again.\n");
	(void) alarm (MAXALARM);
	settty ();
	for (;;) {
		register char *namep;
		namep = crypt (xgetpass ("Password: "), pwd->pw_passwd);
		if (!strcmp (namep, pwd->pw_passwd)) {
			prttime ((long ) (MAXALARM - alarm (0)) / 60);
			break;
		}
		fprintf (stderr, "Password incorrect\n");
	}
	unsettty ();
	exit (0);
}

int ttyset;
struct sgttyb outstty;

settty ()
{
    register int tmp;

    for (tmp = 1; tmp < NSIG; ++tmp) {
	switch (tmp) {
	case SIGHUP:
	case SIGTERM:
	    break;
	default:
	    (void) signal (tmp, SIG_IGN);
	    break;
	}
    }

    if (gtty (0, &outstty) >= 0) {
	ttyset = 1;
	tmp = outstty.sg_flags;
	outstty.sg_flags &= ~ECHO;
	if (0 > stty (0, &outstty)) {
	    fprintf (stderr, "Can't set tty modes.\n");
	    exit (1);
	}
	outstty.sg_flags = tmp;
    }
}

unsettty ()
{
    if (ttyset)
	(void) stty (0, &outstty);
}

char *
xgetpass (prompt)
char *prompt;
{
	register char *p;
	register int c;
	static char pbuf[9];

	fprintf (stderr, prompt);
	for (p = pbuf; (c = getchar ()) != '\n' && c != EOF; ) {
		if (p < &pbuf[8])
			*p++ = c;
	}
	*p = '\0';
	fprintf (stderr, "\n");
	return pbuf;
}

/*
 * prttime prints a time in hours and minutes.
 */
prttime (tim)
long tim;
{
	printf ("You were gone for ");
	if (tim >= 60)
		printf ("%d:%02d\n", tim / 60, tim % 60);
	else if ((tim %= 60) > 0)
		printf ("%d minute%s\n", tim, tim == 1 ? "" : "s");
	else
		printf ("less than a minute\n");
	return;
}

/*
 * r1bindex (str, chr) stands for Right plus 1 or Beginning index of
 *      chr in str.  I.e. return ptr 1 past LAST occurance of chr in
 *      str, OR beginning of the string if str doesn't contain chr.
 */

char *
r1bindex (str, chr)
register char *str;
register int chr;
{
	register char *cp;

	for (cp = str; *cp; cp++) ;
	--cp;
	while (cp >= str && *cp != chr)
		--cp;
	return ++cp;
}

#define ROOTUID 0

struct passwd *
whoisthis ()
{
	struct stat statbuf;
	register int uid;
	register struct passwd *pwd;
	extern struct passwd *really();
	extern struct passwd *getpwuid();

	if (   (   fstat (0, &statbuf) >= 0
		&& (uid = statbuf.st_uid) != ROOTUID
	       )
	    || (uid = getuid()) != ROOTUID
	   ) {
		setpwent();
		pwd = getpwuid (uid);
		endpwent();
		if (NULL != pwd)
			return pwd;
	}
	return really ();
}

struct passwd *
really ()
{
	register char *rootpass;
	register struct passwd *pwd;
	extern struct passwd *getpwuid();
	extern struct passwd *getpwnam();

	setpwent();
	pwd = getpwuid (ROOTUID);
	endpwent();
	rootpass = strsav (pwd->pw_passwd);
	for (;;) Block {
		register int nwho;
		char who[20];
		fprintf (stderr, "Who is this, really?\n");
		(void) fflush(stdout);
		who[0] = '\0';
		(void) fgets (who, sizeof who - 2, stdin);
		nwho = strlen(who);
		if (who[nwho - 1] == '\n')
			who[--nwho] = '\0';
		if (nwho != 0) {
		    setpwent();
		    pwd = getpwnam (who);
		    endpwent();
		    if (NULL != pwd) {
			    pwd->pw_passwd = rootpass;
			    return pwd;
		    }
		}
	}
}

char *
strsav (str)
register char *str;
{
    register char *sav;

    if (!(sav = malloc ((unsigned int) strlen (str) + 1))) {
	fprintf (stderr, "Ran out of memory\n");
	exit (1);
    }
    (void) strcpy (sav, str);
    return sav;
}