#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <utmp.h>

#define F_MSK O_RDWR|O_CREAT

void sleep(unsigned s);

int utmp_fd=0;
char utmp_file[50] = UTMP_FILE; /* default */

struct utmp *getutent (void)
{	static union {	struct utmp tmp;
					char buf[sizeof(struct utmp)];
		     } j;

	if (utmp_fd <= 0)	/* file not open yet */
		if (utmp_fd = open (utmp_file, F_MSK), utmp_fd <= 0)
			return NULL;
	if (read (utmp_fd,j.buf,sizeof(j.buf)) < sizeof(j.buf))
		return NULL;

	return &j.tmp;
}

void setutent (void)
{	int x;

	if (utmp_fd)
		lseek(utmp_fd,0,SEEK_SET);
	else	/* another application might be reading utmp */
		for(x=0;x<10 &&	(utmp_fd = open (utmp_file, F_MSK)) <0;x++)
			sleep(1);

	if(utmp_fd < 0)
		fputs("utmp: Can't open UTMP file !!\n",stderr);
}

void endutent (void)
{	if (utmp_fd)
	{	close (utmp_fd);
		utmp_fd=0;
	}
}

void pututline(struct utmp *w)
{	struct utmp t;
	long c,s=sizeof(struct utmp);

	time(&w->ut_time);
	
	if(utmp_fd <= 0) setutent();
	
	if(utmp_fd > 0)
	{	do
		{	c=read(utmp_fd,&t,s);
		}while(strncmp(t.ut_line,w->ut_line,strlen(t.ut_line)) && c>0);

		if(c>0)				/* entry found so we can overwrite */
			lseek(utmp_fd,-s,SEEK_CUR);	/* if not then append */
		write(utmp_fd,w,s);
	}
}

void utmpname(char *file)
{	if(utmp_fd > 0)
	{	close(utmp_fd);
		utmp_fd=0;
	}
	if(strlen(file) > 49) return;
	strcpy(utmp_file,file);
}
