#include <net-snmp/net-snmp-config.h>

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif

#if HAVE_DMALLOC_H
#include <dmalloc.h>
#endif

#include <net-snmp/types.h>
#include <net-snmp/output_api.h>

#include <net-snmp/library/snmp_transport.h>
#include <net-snmp/library/snmpSTDDomain.h>
#include <net-snmp/library/tools.h>

oid netsnmp_snmpSTDDomain[] = { TRANSPORT_DOMAIN_STD_IP };
static netsnmp_tdomain stdDomain;

/*
 * Return a string representing the address in data, or else the "far end"
 * address if data is NULL.  
 */

static char *
netsnmp_std_fmtaddr(netsnmp_transport *t, void *data, int len)
{
    char *buf;
    DEBUGMSGTL(("domain:std","formatting addr.  data=%x\n",t->data));
    if (t->data) {
        netsnmp_std_data *data = (netsnmp_std_data*)t->data;
        buf = (char*)malloc(SNMP_MAXBUF_MEDIUM);
        if (!buf)
            return strdup("STDInOut");
        snprintf(buf, SNMP_MAXBUF_MEDIUM, "STD:%s", data->prog);
        DEBUGMSGTL(("domain:std","  formatted:=%s\n",buf));
        return buf;
    }
    return strdup("STDInOut");
}



/*
 * You can write something into opaque that will subsequently get passed back 
 * to your send function if you like.  For instance, you might want to
 * remember where a PDU came from, so that you can send a reply there...  
 */

static int
netsnmp_std_recv(netsnmp_transport *t, void *buf, int size,
		 void **opaque, int *olength)
{
    int rc = -1;

    DEBUGMSGTL(("domain:std","recv on sock %d.  data=%x\n",t->sock, t->data));
    while (rc < 0) {
        rc = read(t->sock, buf, size);
        DEBUGMSGTL(("domain:std","  bytes: %d.\n", rc));
        if (rc < 0 && errno != EINTR) {
            DEBUGMSGTL(("netsnmp_std", " read on fd %d failed: %d (\"%s\")\n",
                        t->sock, errno, strerror(errno)));
            break;
        }
        if (rc == 0) {
            /* 0 input is probably bad since we selected on it */
            return -1;
        }
        DEBUGMSGTL(("netsnmp_std", "read on stdin got %d bytes\n", rc));
    }

    return rc;
}



static int
netsnmp_std_send(netsnmp_transport *t, void *buf, int size,
		 void **opaque, int *olength)
{
    int rc = -1;

    DEBUGMSGTL(("domain:std","send on sock.  data=%x\n", t->data));
    while (rc < 0) {
        if (t->data) {
            netsnmp_std_data *data = (netsnmp_std_data*)t->data;
            rc = write(data->outfd, buf, size);
        } else {
            /* straight to stdout */
            rc = write(1, buf, size);
        }
        if (rc < 0 && errno != EINTR) {
            break;
        }
    }
    return rc;
}

static int
netsnmp_std_close(netsnmp_transport *t)
{
    DEBUGMSGTL(("domain:std","close.  data=%x\n", t->data));
    if (t->data) {
        netsnmp_std_data *data = (netsnmp_std_data*)t->data;
        close(data->outfd);
        close(t->sock);

        /* kill the child too */
        DEBUGMSGTL(("domain:std"," killing %d\n", data->childpid));
        kill(data->childpid, SIGTERM);
        sleep(1);
        kill(data->childpid, SIGKILL);
        /* XXX: set an alarm to kill harder the child */
    } else {
        /* close stdout/in */
        close(1);
        close(0);
    }
    return 0;
}



static int
netsnmp_std_accept(netsnmp_transport *t)
{
    DEBUGMSGTL(("domain:std"," accept data=%x\n", t->data));
    /* nothing to do here */
    return 0;
}

/*
 * Open a STDIN/STDOUT -based transport for SNMP.
 */

netsnmp_transport *
netsnmp_std_transport(const char *instring, size_t instring_len,
		      const char *default_target)
{
    netsnmp_transport *t;

    t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
    if (t == NULL) {
        return NULL;
    }
    memset(t, 0, sizeof(netsnmp_transport));

    t->domain = netsnmp_snmpSTDDomain;
    t->domain_length =
        sizeof(netsnmp_snmpSTDDomain) / sizeof(netsnmp_snmpSTDDomain[0]);

    t->sock = 0;
    t->flags = NETSNMP_TRANSPORT_FLAG_STREAM | NETSNMP_TRANSPORT_FLAG_TUNNELED;

    /*
     * Message size is not limited by this transport (hence msgMaxSize
     * is equal to the maximum legal size of an SNMP message).  
     */

    t->msgMaxSize = 0x7fffffff;
    t->f_recv     = netsnmp_std_recv;
    t->f_send     = netsnmp_std_send;
    t->f_close    = netsnmp_std_close;
    t->f_accept   = netsnmp_std_accept;
    t->f_fmtaddr  = netsnmp_std_fmtaddr;

    /*
     * if instring is not null length, it specifies a path to a prog
     * XXX: plus args
     */
    if (instring_len == 0 && default_target != NULL) {
	instring = default_target;
	instring_len = strlen(default_target);
    }

    if (instring_len != 0) {
        int infd[2], outfd[2];  /* sockets to and from the client */
        int childpid;

        if (pipe(infd) || pipe(outfd)) {
            snmp_log(LOG_ERR,
                     "Failed to create needed pipes for a STD transport");
            netsnmp_transport_free(t);
            return NULL;
        }

        childpid = fork();
        /* parentpid => childpid */
        /* infd[1]   => infd[0] */
        /* outfd[0]  <= outfd[1] */

        if (childpid) {
            netsnmp_std_data *data;
            
            /* we're in the parent */
            close(infd[0]);
            close(outfd[1]);

            data = SNMP_MALLOC_TYPEDEF(netsnmp_std_data);
            if (!data) {
                snmp_log(LOG_ERR, "snmpSTDDomain: malloc failed");
                netsnmp_transport_free(t);
                return NULL;
            }
            t->data = data;
            t->data_length = sizeof(netsnmp_std_data);
            t->sock = outfd[0];
            data->prog = strdup(instring);
            data->outfd = infd[1];
            data->childpid = childpid;
            DEBUGMSGTL(("domain:std","parent.  data=%x\n", t->data));
        } else {
            /* we're in the child */

            /* close stdin */
            close(0);
            /* copy pipe output to stdout */
            dup(infd[0]);

            /* close stdout */
            close(1);
            /* copy pipe output to stdin */
            dup(outfd[1]);
            
            /* close all the pipes themselves */
            close(infd[0]);
            close(infd[1]);
            close(outfd[0]);
            close(outfd[1]);

            /* call exec */
            system(instring);
            /* XXX: TODO: use exec form instead; needs args */
            /* execv(instring, NULL); */
            exit(0);

            /* ack...  we should never ever get here */
            snmp_log(LOG_ERR, "STD transport returned after execv()\n");
        }
    }            

    return t;
}

netsnmp_transport *
netsnmp_std_create_tstring(const char *instring, int local,
			   const char *default_target)
{
    return netsnmp_std_transport(instring, strlen(instring), default_target);
}

netsnmp_transport *
netsnmp_std_create_ostring(const u_char * o, size_t o_len, int local)
{
    return netsnmp_std_transport((const char*)o, o_len, NULL);
}

void
netsnmp_std_ctor(void)
{
    stdDomain.name = netsnmp_snmpSTDDomain;
    stdDomain.name_length = sizeof(netsnmp_snmpSTDDomain) / sizeof(oid);
    stdDomain.prefix = (const char **)calloc(2, sizeof(char *));
    stdDomain.prefix[0] = "std";

    stdDomain.f_create_from_tstring     = NULL;
    stdDomain.f_create_from_tstring_new = netsnmp_std_create_tstring;
    stdDomain.f_create_from_ostring     = netsnmp_std_create_ostring;

    netsnmp_tdomain_register(&stdDomain);
}
