#include <sys/unix.h>
#include <sys/devtty.h>
#include "login.h"

extern int ERRNO;

void field();
void readline();

main( argc, argv )
int	argc;
char	*argv[];
{
	char	login[32],
		password[32],
		bit[64],
		line[128],
		vhome[32], vpath[32], vname[32], vrname[32];
	int	users;
	char	*envp[16];
	char	*fname();

	signal( SIGINT, SIG_IGN );

	/* Infinite attempts to login are allowed */
	while(1)
	{
		/* Try and illicit some response from the user */
		fprintf( stdout, "login: " );
		readline( stdin, login );
		fprintf( stdout, "password: " );
		ioctl( stdin, SETNEC, 1 );
		readline( stdin, password );
		ioctl( stdin, SETNEC, 0 );
		fprintf( stdout, "\n" );
		
		/* Hunt through /etc/passed looking for the user */
		if( users=open("/etc/passwd",O_RDONLY), ERRNO )
		{
			fprintf( stderr, "login: can't open /etc/passwd (%i)\n", ERRNO );
			_exit(-1);
		}	
		while( 1 )
		{
			readline( users, line );
			if( *line == 0 )
			{
				fprintf(stdout,"Incorrect login\n");
				break;
			}
			field( line, bit, 0 );
			if( !strcmp( bit, login ) )
			{
				field( line, bit, 1 );
				if( strcmp( bit, password ) )
				{
					fprintf(stdout,"Incorrent login\n");
					break;
				}
				/* Overlay ourselves with a shell */
				field( line, bit, 5 );
				chdir( bit );
				strcpy( vhome, "home=" );
				strcat( vhome, bit );
				field( line, bit, 2 );
				setuid( atoi(bit) );
				field( line, bit, 3 );
				setgid( atoi(bit) );
				strcpy( vpath, "path=/bin:/usr/bin" );
				field( line, bit, 0 );
				strcpy( vname, "name=" );
				strcat( vname, bit );
				field( line, bit, 4 );
				strcpy( vrname, "realname=" );
				strcat( vrname, bit );
				field( line, bit, 6 );
				envp[0]=vhome;
				envp[1]=vpath;
				envp[2]=vname;
				envp[3]=vrname;
				envp[4]=(char*)0;
				envp[5]=fname(bit);
				envp[6]=(char*)0;
				execve( bit, &envp[5], &envp[0] );
				fprintf(stderr,"login: execve of [%s] failed (%i)\n",bit,ERRNO);
				_exit();
			}
		}
		close(users);
	}
}


void field( src, dst, num )
char	*src,
	*dst;
int	num;
{
	char	*pos = src;
	while( num && *pos )
		if( *pos++ == ':' )
			num--;
	while( *pos && (*pos!=':') )
		*dst++ = *pos++;
	*dst = 0;
}

void readline( f, dst )
int	f;
char	*dst;
{
	while( read(f,dst,1) )
		if( *dst == '\n' )
			break;
		else
			dst++;
	*dst = 0;
}

char *fname( path )
char	*path;
{
	int	i = strlen(path);
	char	*retval = path+i-1;

	while( i-- && (*retval!='/') )
		retval--;
	return(retval+1);
}

