V9/cmd/emacs/findtty.c

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

#include <stdio.h>
#include "stddefs.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <utmp.h>

/* Returns a pointer to a character string containing the tty name of a
 * logged-on user.  If the user is logged on more than once, the tty
 * returned is the one that has been used most recently.  If the user is
 * not presently logged on, the null string is returned.  Each call to
 * findtty returns a pointer to the same data area, so the string must
 * be copied if it is to be used again.
 *
 * NOTE: if this code is compiled with the "-DMAIN" option, then a main
 * program will be produced, instead of a function.  The main program
 * takes one user name as argument and outputs the ttyname on standard
 * output.
 *
 * J. Leth, IH 6E-318, x6133.
 */

#define NAMELEN	8
	/* Max. number of characters in a login name */
#define TTYLEN	8
	/* Max. number of characters in a tty name */

#ifndef MAIN
char *
findtty(user)
	char *user;	/* user login name */
{

#else
main(argc, argv)
	int argc;
	char *argv[];
{
	char *user;
#endif

	extern long ftime();
	extern int strcmp();

	FILE *f;
	struct utmp buf;
	long ttytime = 0L;
		/* Holds latest access time found for requested user */
	static char ttyname[TTYLEN+1];
		/* Holds name of tty with that access time */
	long acc_time = 0L;
		/* Access time of tty currently being considered */
	char *utmp = "/etc/utmp";

	if((f=fopen(utmp,"r"))==NULL) {
		errexit("findtty: can't open %s file.\n", utmp);
	}

	ttyname[0] = NUL;

#ifdef MAIN
	if (argc != 2) {
		usage("Usage:\tfindtty <login-id>\n\
	Outputs the name of the most recently-used terminal on which\n\
	user <login-id> is currently logged in.\n");
	}

	user = argv[1];
#endif

	while(fread(&buf,sizeof(buf),1,f) == 1) {
		/* Search utmp file for logins of the designated user.
		 * For each one found, see if the access time is later
		 * than the latest one so far; if it is, remember the
		 * ttyname and ttytime.
		 */

		if(strncmp(buf.ut_name, user, NAMELEN) != 0)	continue;

		if((acc_time=ftime(buf.ut_line)) > ttytime) {
			ttytime = acc_time;
			strncpy(ttyname, buf.ut_line, TTYLEN);
			ttyname[TTYLEN] = '\0';
				/* just to be sure string is terminated */
		}
	}
#ifndef MAIN
	return(ttyname);
#else
	printf("%s\n", ttyname);
#endif
}

long
ftime(s)
char *s;
{
	/* Returns the time of last access for the named device.
	 * The name given as taken as the last component of the device
	 * pathname.  The first component, "/dev/" is supplied by this
	 * routine.  If the device doesn't exist, -1L is returned.
	 */

	char dev[20];
	struct stat statb;

	strcpy(dev,"/dev/");
	strcat(dev,s);
	if( stat(dev,&statb)<0 )
		return(-1L);
	return( statb.st_atime );
}