/*
This source file is part of Scol
For the latest info, see http://www.scolring.org

Copyright (c) 2011 Stephane Bisaro, aka Iri <iri@irizone.net>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt

For others informations, please contact us from http://www.scolring.org/
*/

#include "main.h"


int NETNET_computerName (mmachine m)
{
    char *name = NULL;

    MMechostr (MSKDEBUG, "NETNET_computerName entering\n");

    name = malloc (sizeof (char)*128);
    if (0 == gethostname (name, 127))
        Mpushstrbloc (m, name);
    else
        MMpush (m, NIL);
    free (name);
    return 0;
}

/* The Scol prototype should be fun [S] [[S I S] r1] */
int NETNET_computerInfos2 (mmachine m)
{
    int mname;
    int res, i = 0, n = 0;
    struct addrinfo *resadr = NULL;
    struct addrinfo *padr = NULL;
    struct addrinfo hints;
    const char *name = NULL;

    MMechostr (MSKDEBUG, "NETNET_computerInfos entering\n");

    mname = MMpull (m);
    if (mname == NIL)
        name = "127.0.0.1";
    else
        name = MMstartstr (m, MTOP (mname));

    memset (&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_CANONNAME;
    hints.ai_protocol = IPPROTO_TCP;

    res = getaddrinfo (name, NULL, &hints, &resadr);

    if (res != 0)
    {
        MMechostr (MSKDEBUG, "NETNET_computerInfos error : %s\n", gai_strerror (res));
        MMpush (m, NIL);
        return 0;
    }

    for (padr = resadr; padr != NULL ; padr = padr->ai_next)
    {
        Mpushstrbloc (m, padr->ai_canonname);
        MMpush (m, ITOM (padr->ai_family));
        Mpushstrbloc (m, padr->ai_addr->sa_data);
        MMpush (m, ITOM (3));
        MBdeftab (m);
        n++;
    }
    MMpush (m, NIL);
    for (i = 0; i < n; i++)
    {
        MMpush (m, ITOM (2));
        MBdeftab (m);
    }
    freeaddrinfo (resadr);
    return 0;
}

int NETNET_computerInfos (mmachine m)
{
    int mname;
    int i = 0, n = 0;
    struct hostent *sh;
    struct in_addr addr;
    const char *name = NULL;
    char **pAlias;

    MMechostr (MSKDEBUG, "NETNET_computerInfos entering\n");

    mname = MMpull (m);
    if (mname == NIL)
        name = "127.0.0.1";
    else
        name = MMstartstr (m, MTOP (mname));


    sh = gethostbyname (name);

    if (sh == NULL)
    {
        MMechostr (MSKDEBUG, "NETNET_computerInfos error : %d\n", h_errno);
        MMpush (m, NIL);
        return 0;
    }

    Mpushstrbloc (m, sh->h_name);

    for (i = 0; sh->h_aliases[i] != NULL; i++)
    {
        Mpushstrbloc (m, sh->h_aliases[i]);
        n++;
    }
    MMpush (m, NIL);
    if (n > 0)
    {
        for (i = 0; i < n; i++)
        {
            MMpush (m, ITOM (2));
            MBdeftab (m);
        }
    }
    MMpush (m, ITOM((int) sh->h_addrtype));
    n = 0;
    for (i = 0; sh->h_addr_list[i] != NULL; i++)
    {
        addr.s_addr = *(u_long *) sh->h_addr_list[i];
        Mpushstrbloc (m, inet_ntoa(addr));
        n++;
    }
    MMpush (m, NIL);
    if (n > 0)
    {
        for (i = 0; i < n; i++)
        {
            MMpush (m, ITOM (2));
            MBdeftab (m);
        }
    }

    MMpush (m, ITOM (4));
    MBdeftab (m);

    return 0;
}


char* net_net_name[NET_NET_PKG_NB]=
{
    "NET_AF_INET", "NET_AF_INET6", "NET_AF_UNSPEC",

    "_netLocalName",
    "_netHostInfos"
};

int (*net_net_fun[NET_NET_PKG_NB])(mmachine m)=
{
    SCTYPVAR (NET_AF_INET), SCTYPVAR (NET_AF_INET6), SCTYPVAR (NET_AF_UNSPEC),

    NETNET_computerName,
    NETNET_computerInfos
};

int net_net_narg[NET_NET_PKG_NB]=
{
    TYPVAR, TYPVAR, TYPVAR,

    0,       /* _netLocalName */
    1       /* _netHostInfos */
};

char* net_net_type[NET_NET_PKG_NB]=
{
    "I", "I", "I",

    "fun [] S",                          /* _netLocalName */
    "fun [S] [S [S r1] I [S r1]]"         /* _netHostInfos */
};



int SCOLnetworksLoadAPI (mmachine m)
{
    int k;

    MMechostr(MSKDEBUG, "SCOLnetworksLoadAPI: entering\n");

    k = PKhardpak (m, "Net_Networks", NET_NET_PKG_NB, net_net_name, net_net_fun, net_net_narg, net_net_type);
    return k;
}

