AUSAM/source/S/who.c

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

#
/*
**  	who   [-d] [-s] [-f] [-l] [-o] [ wtmp ]|[ am i ]
** 
**
**	oct  77		piers lauder
**	       		new wtmp/utmp formats
**	feb  78		piers lauder
**			ausam
**	apr  79		davec
**			C flag
**	june 79		michael coorey
**			rewritten, output reformatted
**
**
**
**	lists names and details of unix users
**	flags	d	initial directory
**		s	initial shell
**		f	firstname
**		l	lastname
**		C	class
**		o	other information
**
**	usually accesses files 	/etc/utmp
**			    or	/usr/adm/wtmp
**
**
**
**
**		output format:
**
**	type	name	uid		ttyid	time		newtime
**					newuid
**	1-8	9-24	25-29	30-32	33-40	41-52	53-56	57-68
**	( who on default file is left-shifted 8 chars (does not include type or uid) )
*/





#include	<local-system>		/* system paramters */
#include	<utmp.h>		/* utmp/wtmp formats */
#include	<passwd.h>		/* user details on passwd file */
#include	<class.h>		/* user class info */
#include	<stat16.h>		/* format for "fstat" */





struct	utmp	buf[512/UTMPSIZ];	/* buffer for utmp/wtmp records */
int		fin,fout;		/* buffered input/output file descriptors */
char		utmpf[]		"/etc/utmp";





main(argc,argv)

int	argc;
char	*argv[];

{
	static struct flags			/* flags */
	{
		char	d,s,f,l,o,C,locking;
		int	yes;
	}
	flg;
	register struct flags	*flag	= &flg;
	struct pwent		pe;		/* password entry for user */
	int			pwentry;	/* true if there exists a pwent for current user */
	register struct pwent	*pwe;
	char			pbuf[SSIZ];	/* strings from password entry */
	register struct utmp	*p;		/* pointer to utmp/wtmp record */
	char			tty;		/* users tty */
	int			status;		/* exit status */
	int			tmpsiz;		/* size of input buffer */
	char			*ifile;		/* input file name */
	char			c;





	/* set flag arguments */
	flag->yes = 0;
	while ( argc > 1 && argv[1][0] == '-' )
	{
		while ( c = *(++argv[1]) ) 
		{
			switch( c )
			{
			case 'd':	
				flag->d++;	
				break;
			case 's':	
				flag->s++;	
				break;
			case 'f':	
				flag->f++;	
				break;
			case 'l':	
				flag->l++;	
				break;
			case 'o':	
				flag->o++;	
				break;
			case 'C':	
				flag->C++;	
				break;
			default:	
				printf("bad flag  %c\n",c);
				continue;
			}
			flag->yes++;
		}
		argc--;
		argv++;
	}



	/* set and open input file */
	if(argc == 2)
		ifile = argv[1];
	else	ifile = utmpf;
	fin = open(ifile, 0);
	if( fin < 0 )
	{
		perror(ifile);
		exit( 1 );
	}

	{
		struct statbuf	sbuf;

		fstat( fin, &sbuf );
		if ( sbuf.sb_flags & IFLOCK )
		{
			flag->locking++;
		}
	}

	/* set output file descriptor to 3 so output buffered */
	fout = dup(1);
	close(1);

	/* set user tty */
	if (argc==3)
		tty = ttyn(0);





	/* step thru utmp/wtmp file */
	while( (tmpsiz=read(fin,buf,sizeof buf)) > 0 )
	{
		if ( flag->locking )
			if ( unlock() == -1 )
			{
				prints( 2, "unlock - " );
				perror( ifile );
				status = 1;
				goto finish;
			}

		/* step thru buffer */
		for( p=buf; (tmpsiz =- UTMPSIZ)>=0; p++ )
		{
			/* - who am i - irelevant record */
			if( (argc==3)   &&   (tty!=p->u_ttyid) )
				continue;
			/*  -  who  -  who /etc/utmp  -  irrelevant record */
			if( (ifile==utmpf) && (p->u_type != U_TYPE) )
				continue;
			switch( p->u_type )
			{
			case U_TYPE:	/* user record */
			case O_TYPE:	/* log off record */

				/* print type except for default listing */
				if( !(argc==1) )
					if( p->u_type == U_TYPE )
						putchar( '\t' );
					else	printf( "logoff\t" );

				if ( p->u_type == U_TYPE )
					/* print name */
					if( !flag->yes && p->u_u_name[0] )
						/* no options and name in utmp */
					{
						char	name[9],*s;
						int	j;
						/* ensure name is \0 terminated */
						s=name;
						for( j=0; j<8; j++ )
							*s++ = p->u_u_name[j];
						*s = '\0';
						pname( name );
					}
					else
						/* get name from passwd file */
					{
						pwe = &pe;
						if(pwe->pw_uid != p->u_u_id)
						{
							pwe->pw_uid = p->u_u_id;
							pwentry = (getpwlog(pwe,pbuf,SSIZ) >0);
						}
						if(pwentry)
							pname(pwe->pw_strings[LNAME]);
						else	pname("");
					}
				else
				{
					printf( "\t\t" );
					if(flag->yes && pwe->pw_uid != p->u_u_id)
					{
						pwe->pw_uid = p->u_u_id;
						pwentry = (getpwlog(pwe,pbuf,SSIZ)>0);
					}
				}

				if ( argc != 1 )
					/* print uid */
					printf( "%-5d\t", p->u_u_id );

				/* print tty time */
				printf( "tty%c\t%12.12s",
				p->u_ttyid,ctime(p->u_logintime)+4 );

				/* options */
				if( flag->yes && pwentry )
				{
					if( flag->f | flag->l | flag->d | flag->s | flag->C )
					{
						putchar( '\t' );
						if( flag->f )
							printf( "%s ",pwe->pw_strings[FIRSTNAME] );
						if( flag->l )
							printf( "%s ",pwe->pw_strings[LASTNAME] );
						if( flag->d )
							printf( "%s ",pwe->pw_strings[DIRPATH] );
						if( flag->s )
							if( *(pwe->pw_strings[SHELLPATH]) == '\0' )
								printf( "/bin/sh " );
							else   printf( "%s ",pwe->pw_strings[SHELLPATH] );
						if( flag->C )
							/* print class name */
						{
							int	word,bit;
							for( word=0; word!=CMASKSIZE; word++ )
								for( bit=15; bit>=0; --bit )
									if( pwe->pw_cmask[word] & (1<<bit) )
										printf( "%s ",classes[word*16+15-bit].c_name );
						}
						putchar( '\n' );
					}
					if( flag->o )
						printf( "\t%s\n\n",pwe->pw_strings[OTHER] );
				}
				else
					putchar( '\n' );


				/*  - who am i -   done */
				if( argc == 3 )
					goto finish;
				break;



			case W_TYPE:	/* async process */
				printf( "async\t\t\t%-5d\t\t%12.12s\n",
				p->w_uid,ctime(p->w_finishtime)+4 );
				break;
			case SU_TYPE: /* super user */
				printf( "SUPER\t\t\t%-5d > %-5d\t%12.12s\n",
				p->su_olduid,p->su_newuid,ctime(p->su_usetime)+4 );
				break;
			case D_TYPE:	/* date change */
				printf( "DATE\t\t\t\t\t%12.12s",
				ctime(p->d_oldtime)+4 );
				printf( " to %12.12s\n",
				ctime(p->d_newtime)+4 );
				break;
			case S_TYPE:	/* system boot */
				printf( "BOOT\t\t\t\t\t%12.12s\n",
				ctime(p->s_boottime)+4 );
				break;
			default:	
				write(2,"bad wtmp\n",9);
				status = 1;
				goto finish;
			}
		}

		if ( flag->locking )
		{
			pwclose();	/* passwd file maybe */
			if ( readlock( fin ) == -1 )
			{
				prints( 2, "lock - " );
				perror( ifile );
				status = 1;
				goto finish;
			}
		}
	}


	/* check for error */
	if( tmpsiz < 0 )
	{
		perror(ifile);
		status=1;
		goto finish;
	}



	/*  - who am i -  failed */
	if( argc==3 )
	{
		printf( "nobody\t\tbad utmp\n" );
		status = 1;
	}



finish:	/* exit with status */
	flush();
	exit(status);
}





/* print user name */
pname(s)
char *s;
{
	register int i;
	register char *p;

	p=s;
	if( *p == '\0' )
	{
		*p++ = '?';
		*p-- = '\0';
	}
	for(i=0; *p++ != '\0'; i++);

	printf("%-.15s",s);

	if( i<8 ) putchar('\t');
	putchar('\t');
}