/* ``The contents of this file are subject to the Erlang Public License,
 * Version 1.1, (the "License"); you may not use this file except in
 * compliance with the License. You should have received a copy of the
 * Erlang Public License along with this software. If not, it can be
 * retrieved via the world wide web at http://www.erlang.org/.
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
 * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
 * AB. All Rights Reserved.''
 * 
 *     $Id$
 */
#include 	<stdio.h>
#include 	<string.h>
#include 	<stropts.h>
#include 	<poll.h>
#include 	<unistd.h>
#include 	<sys/types.h>
#include 	<sys/stat.h>
#include	<fcntl.h>
#include	<sys/uio.h>

	/* arguments */
#define		OWNPATH		1
#define		NARG		1

	/* status codes */
#define		OK		0
#define 	NOT_OK		1

	/* hardwired constants*/
#define 	PIPENAME	"syslog.otp"
#define		DIE_CMD		"die"
#define		ONLY_STDIN_CMD	"only_stdin"
#define 	BUFFER_SIZE	1001
#define 	MAXPATH_SIZE	1001
#define		STDIN		0
#define		STDOUT		1
#define		HEADER_SIZE	2
#define		WAIT		10
#define		INTERVAL	1
#define		FALSE		0
#define		TRUE		1
#define		FDS_STDIN	0
#define		FDS_PIPE	1

main(int argc, char *argv[])
/*	usage: ferrule ownpath */
{
    int		i, pipe_fd;
    long	int	nfds=2L;
    char	buf[BUFFER_SIZE], pipename[MAXPATH_SIZE], packet_size[2];
    struct	pollfd	fds[2];
    struct	stat	stat_buf;
    
    /* enough arguments? */
    if(argc < NARG+1)
	exit(NOT_OK);
    
    /* make pipe name */
    strcpy(pipename, argv[OWNPATH]);
    strcat(pipename, "/");
    strcat(pipename, PIPENAME);
    
    /* wait for creation of pipe */
    for(i=WAIT; i>0; i--)
	if(stat(pipename, &stat_buf) == 0)
	    break;
	else{
	    if(i == 0)
		exit(NOT_OK);
	    else
		sleep(INTERVAL);
	}
    
    /* open pipe, exit if error */
    if((pipe_fd = open(pipename, O_RDONLY | O_NONBLOCK)) == -1)
	exit(NOT_OK);
    
    /* setup for pipe */
    fds[FDS_PIPE].fd = pipe_fd;
    fds[FDS_PIPE].events = POLLRDNORM;
    fds[FDS_PIPE].revents = 0;
    
    /* setup for stdin */
    fds[FDS_STDIN].fd = STDIN;
    fds[FDS_STDIN].events = POLLRDNORM;
    fds[FDS_STDIN].revents = 0;
    
    /* loop */
    while(1){
	/* wait for input */
	if(poll(&fds[0], nfds, INFTIM) == -1)
	    exit(NOT_OK);

	/* analyse input from pipe */
	if(fds[FDS_PIPE].revents != 0){

	    /* pipe error, error exit */
	    if((fds[FDS_PIPE].revents & (POLLHUP | POLLERR | POLLNVAL)) != 0)
		exit(NOT_OK);

	    /* read pipe and write to stdout, exit if error */
	    if((fds[FDS_PIPE].revents & POLLRDNORM) != 0){
		i=0;
		do{
		    read(pipe_fd, &buf[i++], (size_t)1);
		}while(buf[i-1] != '\n');
		i--;

		/* send if string is not empty */
		if(i != 0){
		    /* make packet size, [0]=MSB, [1]=LSB */
		    packet_size[0] = (i >> 8) & 0xff;
		    packet_size[1] = i & 0xff;

		    /* send to OTP process */
		    if(write(STDOUT, packet_size, HEADER_SIZE) != HEADER_SIZE)
			exit(NOT_OK);
		    if(write(STDOUT, buf, i) != i)
			exit(NOT_OK);
		}
	    }
	}

	/* analyse input from stdin */
	if(fds[FDS_STDIN].revents != 0){

	    /* error exit */
	    if((fds[FDS_STDIN].revents & (POLLHUP | POLLERR | POLLNVAL)) != 0)
		exit(NOT_OK);

	    /* read bytes */
	    if((fds[FDS_STDIN].revents & POLLRDNORM) != 0){
		/* get packet size, [0]=MSB, [1]=LSB */
		if(read(STDIN, packet_size, HEADER_SIZE) != HEADER_SIZE)
		    exit(NOT_OK);
		i = (packet_size[0] << 8) | packet_size[1];

		/* get packet */
		if(read(STDIN, buf, i) != i)
		    exit(NOT_OK);

		/* check if die command */
		if(strncmp(DIE_CMD, buf, i) == FALSE)
		    exit(OK);

		/* check if only_stdin command */
		if(strncmp(ONLY_STDIN_CMD, buf, i) == FALSE)
		    nfds=1L;
	    }
	}
    }
}
