/* -------------------------------------------------------------------- */
/* SMS Client, send messages to mobile phones and pagers		*/
/*									*/
/* npipe.c								*/
/*									*/
/*  Copyright (C) 1997,1998,1999 Angelo Masci				*/
/*									*/
/*  This library is free software; you can redistribute it and/or	*/
/*  modify it under the terms of the GNU Library General Public		*/
/*  License as published by the Free Software Foundation; either	*/
/*  version 2 of the License, or (at your option) any later version.	*/
/*									*/
/*  This library is distributed in the hope that it will be useful,	*/
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of	*/
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU	*/
/*  Library General Public License for more details.			*/
/*									*/
/*  You should have received a copy of the GNU Library General Public	*/
/*  License along with this library; if not, write to the Free		*/
/*  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.	*/
/*									*/
/*  You can contact the author at this e-mail address:			*/
/*									*/
/*  angelo@styx.demon.co.uk						*/
/*									*/
/* -------------------------------------------------------------------- */
/* $Id$
   -------------------------------------------------------------------- */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#include "npipe.h"
#include "common/common.h"
#include "logfile/logfile.h"

/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
int create_named_pipe(char *file)
{
	int	create_fifo;


	create_fifo = 1;
	while(create_fifo)
	{
		if (mkfifo(file, O_RDWR|O_CREAT|O_NONBLOCK) == -1)
		{
			if (errno == EEXIST)
			{
				lprintf(LOG_WARNING, "Named Pipe '%s' already exists.\n", file);
				lprintf(LOG_WARNING, "Deleting Named Pipe...\n");

				if (unlink(file) == -1)
				{	lprintf(LOG_WARNING, "Failed to delete Named Pipe...\n");
					return -1;
				}

				lprintf(LOG_WARNING, "Done\n");
			}
			else
			{	return -1;
			}
		}
		else
		{	create_fifo = 0;
		}
	}

	return 0;
}


/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */
int delete_named_pipe(char *file)
{
	return unlink(file);
}


/* -------------------------------------------------------------------- */
/* Read one character from named pipe.					*/
/* If no character is available block.					*/
/* On receipt of 'signal' return with -1 and errno set to EINTR		*/
/*									*/
/* Return Values:							*/
/*	 0 Data Present							*/
/*	-1 Error or receipt of signal					*/
/*	   with 'errno' 0 indicates EOF					*/ 
/* -------------------------------------------------------------------- */
int block_on_named_pipe(char *file)
{
	fd_set 	readfds,
		writefds,
		exceptfds;

	int	nfds,
		rtval,
		fd,
		waiting, 
		c,
		res;

	/* ---------------------------- */


	fd = open(file, O_RDWR|O_NONBLOCK);
	if (fd == -1)
	{	return -1;
	}


	nfds = fd +1;

	FD_ZERO(&writefds);
	FD_ZERO(&readfds);
	FD_ZERO(&exceptfds);

	waiting = TRUE;
	while(waiting)
	{
		FD_SET(fd,&readfds);

		if ((rtval = select(nfds, &readfds, NULL, NULL, NULL)) != 0)
		{
			if (rtval > 0)		/* Select Woken on FDs */
			{
				if (FD_ISSET(fd, &readfds))
				{	
					res = read(fd, &c, 1);
					while(res != 1)
					{
						if (res == -1)
						{
							close(fd);
							return -1;
						}
						else
						if (res == 0)
						{	errno = 0;

							close(fd);
							return -1;
						}

						res = read(fd, &c, 1);
					}

					waiting = FALSE;
				}
			}
			else 
			if (rtval == -1) 	/* Error Return Value */
			{
				close(fd);
				return -1;
			}	
		}
	}

	close(fd);
	return 0;
}



/* -------------------------------------------------------------------- */
/* Read one character from named pipe.					*/
/* If no character is available DO NOT block.				*/
/*									*/
/* Return Values:							*/
/*	 1 Data Present							*/
/*	 0 No Data Present						*/
/*	-1 Error							*/
/* -------------------------------------------------------------------- */
int read_named_pipe(char *file)
{
	int	fd,
		c,
		res;

	/* ---------------------------- */


	fd = open(file, O_RDWR|O_NONBLOCK);
	if (fd == -1)
	{	return -1;
	}


	res = read(fd, &c, 1);
	if (res == -1)
	{
		if (errno == EAGAIN)
		{	res = 0;	/* Would have blocked */
		}
	}

	close(fd);
	return res;
}



/* -------------------------------------------------------------------- */
/* Write one character to named pipe.					*/
/* -------------------------------------------------------------------- */
int write_to_named_pipe(char *file)
{
	int	fd,
		res,
		c;



	fd = open(file, O_RDWR|O_NONBLOCK);
	if (fd == -1)
	{	return -1;
	}


	c = 'X';
	res = write(fd, &c, 1);
	while(res != 1)
	{
		if (res == -1)
		{
			if (errno != EINTR)
			{	return -1;
			}
		}

		res = write(fd, &c, 1);
	}

	close(fd);
	return 0;
}

