#ifndef _WINDOWS

/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** UNIX AF_LOCAL network wrapper
 *
 * @author Mladen Turk
 * @version $Id: uxpipe.c 1442587 2013-02-05 13:49:48Z rjung $
 */


#include "tcn.h"
#include "apr_thread_mutex.h"
#include "apr_poll.h"

/* ### should be tossed in favor of APR */
#include <sys/stat.h>
#include <sys/un.h> /* for sockaddr_un */

#ifdef TCN_DO_STATISTICS
#include "apr_atomic.h"

static volatile apr_uint32_t uxp_created  = 0;
static volatile apr_uint32_t uxp_closed   = 0;
static volatile apr_uint32_t uxp_cleared  = 0;
static volatile apr_uint32_t uxp_accepted = 0;

void uxp_network_dump_statistics()
{
    fprintf(stderr, "NT Network Statistics ..\n");
    fprintf(stderr, "Sockets created         : %d\n", uxp_created);
    fprintf(stderr, "Sockets accepted        : %d\n", uxp_accepted);
    fprintf(stderr, "Sockets closed          : %d\n", uxp_closed);
    fprintf(stderr, "Sockets cleared         : %d\n", uxp_cleared);
}

#endif

#define DEFNAME     "/var/run/tomcatnativesock"
#define DEFNAME_FMT "/var/run/tomcatnativesock%08x%08x"
#define DEFSIZE     8192
#define DEFTIMEOUT  60000

#define TCN_UXP_UNKNOWN     0
#define TCN_UXP_CLIENT      1
#define TCN_UXP_ACCEPTED    2
#define TCN_UXP_SERVER      3

#define TCN_UNIX_MAXPATH    1024
typedef struct {
    apr_pool_t          *pool;
    apr_socket_t        *sock;               /* APR socket */
    int                 sd;
    struct sockaddr_un  uxaddr;
    int                 timeout;
    int                 mode;                 /* Client or server mode */
    char                name[TCN_UNIX_MAXPATH+1];
} tcn_uxp_conn_t;

static apr_status_t APR_THREAD_FUNC
uxp_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    if (t < 0)
        con->timeout = -1;
    else
        con->timeout = (int)(apr_time_as_msec(t));
    return APR_SUCCESS;
}

static apr_status_t APR_THREAD_FUNC
uxp_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t*)sock;
    if (con->timeout < 0)
        *t = -1;
    else
        *t = con->timeout * 1000;
    return APR_SUCCESS;
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
uxp_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_opt_set(con->sock, opt, on);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
uxp_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_opt_get(con->sock, opt, on);
}

static apr_status_t uxp_cleanup(void *data)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)data;

    if (con) {
        if (con->sock) {
            apr_socket_close(con->sock);
            con->sock = NULL;
        }
        if (con->mode == TCN_UXP_SERVER) {
            unlink(con->name);
            con->mode = TCN_UXP_UNKNOWN;
        }
    }

#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&uxp_cleared);
#endif
    return APR_SUCCESS;
}

static apr_status_t APR_THREAD_FUNC
uxp_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_shutdown(con->sock, how);
}

static apr_status_t APR_THREAD_FUNC
uxp_socket_close(apr_socket_t *sock)
{
#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&uxp_closed);
#endif
    return uxp_cleanup(sock);
}

static apr_status_t APR_THREAD_FUNC
uxp_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_recv(con->sock, buf, len);
}


static apr_status_t APR_THREAD_FUNC
uxp_socket_send(apr_socket_t *sock, const char *buf,
                apr_size_t *len)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_send(con->sock, buf, len);
}

static apr_status_t APR_THREAD_FUNC
uxp_socket_sendv(apr_socket_t *sock,
                 const struct iovec *vec,
                 apr_int32_t nvec, apr_size_t *len)
{
    tcn_uxp_conn_t *con = (tcn_uxp_conn_t *)sock;
    return apr_socket_sendv(con->sock, vec, nvec, len);
}

static apr_status_t uxp_socket_cleanup(void *data)
{
    tcn_socket_t *s = (tcn_socket_t *)data;

    if (s->net->cleanup) {
        (*s->net->cleanup)(s->opaque);
        s->net->cleanup = NULL;
    }
#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&uxp_cleared);
#endif
    return APR_SUCCESS;
}

static tcn_nlayer_t uxp_socket_layer = {
    TCN_SOCKET_UNIX,
    uxp_cleanup,
    uxp_socket_close,
    uxp_socket_shutdown,
    uxp_socket_opt_get,
    uxp_socket_opt_set,
    uxp_socket_timeout_get,
    uxp_socket_timeout_set,
    uxp_socket_send,
    uxp_socket_sendv,
    uxp_socket_recv
};

TCN_IMPLEMENT_CALL(jlong, Local, create)(TCN_STDARGS, jstring name,
                                         jlong pool)
{
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    tcn_socket_t   *s   = NULL;
    tcn_uxp_conn_t *con = NULL;
    int sd;
    TCN_ALLOC_CSTRING(name);

    UNREFERENCED(o);
    TCN_ASSERT(pool != 0);

    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        tcn_ThrowAPRException(e, apr_get_netos_error());
        return 0;
    }
#ifdef TCN_DO_STATISTICS
    uxp_created++;
#endif
    con = (tcn_uxp_conn_t *)apr_pcalloc(p, sizeof(tcn_uxp_conn_t));
    con->pool = p;
    con->mode = TCN_UXP_UNKNOWN;
    con->timeout = DEFTIMEOUT;
    con->sd = sd;
    con->uxaddr.sun_family = AF_UNIX;
    if (J2S(name)) {
        strcpy(con->uxaddr.sun_path, J2S(name));
        TCN_FREE_CSTRING(name);
    }
    else
        strcpy(con->uxaddr.sun_path, DEFNAME);
    s = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
    s->pool   = p;
    s->net    = &uxp_socket_layer;
    s->opaque = con;
    apr_pool_cleanup_register(p, (const void *)s,
                              uxp_socket_cleanup,
                              apr_pool_cleanup_null);

    apr_os_sock_put(&(con->sock), &(con->sd), p);

    return P2J(s);

}

TCN_IMPLEMENT_CALL(jint, Local, bind)(TCN_STDARGS, jlong sock,
                                      jlong sa)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED_STDARGS;
    UNREFERENCED(sa);
    TCN_ASSERT(sock != 0);
    if (s->net->type == TCN_SOCKET_UNIX) {
        int rc;
        tcn_uxp_conn_t *c = (tcn_uxp_conn_t *)s->opaque;
        c->mode = TCN_UXP_SERVER;
        rc = bind(c->sd, (struct sockaddr *)&(c->uxaddr), sizeof(c->uxaddr));
        if (rc < 0)
            return errno;
        else
            return APR_SUCCESS;
    }
    else
        return APR_EINVAL;
}

TCN_IMPLEMENT_CALL(jint, Local, listen)(TCN_STDARGS, jlong sock,
                                        jint backlog)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED_STDARGS;

    TCN_ASSERT(sock != 0);
    if (s->net->type == TCN_SOCKET_UNIX) {
        tcn_uxp_conn_t *c = (tcn_uxp_conn_t *)s->opaque;
        c->mode = TCN_UXP_SERVER;
        return apr_socket_listen(c->sock, (apr_int32_t)backlog);
    }
    else
        return APR_EINVAL;
}

TCN_IMPLEMENT_CALL(jlong, Local, accept)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t   *p = NULL;
    tcn_socket_t *a = NULL;
    tcn_uxp_conn_t *con = NULL;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    TCN_THROW_IF_ERR(apr_pool_create(&p, s->pool), p);
    if (s->net->type == TCN_SOCKET_UNIX) {
        apr_socklen_t len;
        tcn_uxp_conn_t *c = (tcn_uxp_conn_t *)s->opaque;
        con = (tcn_uxp_conn_t *)apr_pcalloc(p, sizeof(tcn_uxp_conn_t));
        con->pool = p;
        con->mode = TCN_UXP_ACCEPTED;
        con->timeout = c->timeout;
        len = sizeof(c->uxaddr);
        /* Block until a client connects */
        con->sd = accept(c->sd, (struct sockaddr *)&(con->uxaddr), &len);
        if (con->sd < 0) {
            tcn_ThrowAPRException(e, apr_get_os_error());
            goto cleanup;
        }
    }
    else {
        tcn_ThrowAPRException(e, APR_ENOTIMPL);
        goto cleanup;
    }
    if (con) {
#ifdef TCN_DO_STATISTICS
        apr_atomic_inc32(&uxp_accepted);
#endif
        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
        a->pool   = p;
	    a->net    = &uxp_socket_layer;
        a->opaque = con;
        apr_pool_cleanup_register(p, (const void *)a,
                                  uxp_socket_cleanup,
                                  apr_pool_cleanup_null);
        apr_os_sock_put(&(con->sock), &(con->sd), p);
    }
    return P2J(a);
cleanup:
    if (p)
        apr_pool_destroy(p);
    return 0;
}

TCN_IMPLEMENT_CALL(jint, Local, connect)(TCN_STDARGS, jlong sock,
                                         jlong sa)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    tcn_uxp_conn_t *con = NULL;
    int rc;

    UNREFERENCED(o);
    UNREFERENCED(sa);
    TCN_ASSERT(sock != 0);
    if (s->net->type != TCN_SOCKET_UNIX)
        return APR_ENOTSOCK;
    con = (tcn_uxp_conn_t *)s->opaque;
    if (con->mode != TCN_UXP_UNKNOWN)
        return APR_EINVAL;
    do {
        rc = connect(con->sd, (const struct sockaddr *)&(con->uxaddr),
                     sizeof(con->uxaddr));
    } while (rc == -1 && errno == EINTR);

    if (rc == -1 && errno != EISCONN)
        return errno;
    con->mode = TCN_UXP_CLIENT;

    return APR_SUCCESS;
}

#endif

