/*
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"

static char* net_buffer_alloc ()
{
    char *s;

    s = malloc (sizeof (char) * 512);
    /*memset (s, '\0', 512);*/
    return s;
}







int net_connection_init (void)
{
    #if ((defined _WIN32) || (defined __WIN32__))
    WSADATA wsa;
    int err;

    err = WSAStartup (MAKEWORD (2, 2), &wsa);
    if (err != NO_ERROR)
    {
        MMechostr (MSKDEBUG, "net_connection_init error : WSAStartup failed : %d!\n", err);
        return 1;
    }
    #endif
    return 0;
}

int net_connection_end (SOCKET sock)
{
    if (close (sock) == -1)
    {
        MMechostr (MSKDEBUG, "net_connection_end error : socket %d can not be closed : %d %s\n", sock, errno, strerror (errno));
        return 1;
    }
    return 0;
}

int net_connection_socket (int port, char *iphost)
{
    SOCKET sock;
    SOCKADDR_IN address = { 0 };
    #if defined _WIN32 || defined __WIN32__
    u_long blocmode = 1;
    #endif

    sock = socket (AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET)
    {
        MMechostr (MSKDEBUG, "net_connection_socket error : socket invalid\n");
        net_connection_end (-1);
        return -1;
    }
    #if defined _WIN32 || defined __WIN32__
    if (ioctlsocket (sock, FIONBIO, &blocmode) != NO_ERROR)
        MMechostr (MSKDEBUG, "net_connection_socket error : no operates in blocking mode : %d  %s\n", errno, strerror (errno));
    #elif ((defined linux) || (defined __linux))
    if (0 != fcntl (sock, F_SETFL, O_NONBLOCK))
        MMechostr (MSKDEBUG, "net_connection_socket error : no operates in blocking mode : %d  %s\n", errno, strerror (errno));
    #else

    #endif

    address.sin_port = htons (port);
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr (iphost);
    if (INADDR_NONE == address.sin_addr.s_addr)
    {
        MMechostr (MSKDEBUG, "net_connection_socket error : address IP not converted (inet_addr)\n");
        net_connection_end (sock);
        return -2;
    }

    if (connect (sock, (SOCKADDR *) &address, sizeof (address)) == SOCKET_ERROR)
    {
        MMechostr (MSKDEBUG, "net_connection_socket error : not connected : %d, %s!\n", errno, strerror (errno));
        net_connection_end (sock);
        return -3;
    }

    return sock;
}

/* return 0 if ok */
int net_connection_write (SOCKET sock, char *cmd)
{
    char buffer[NETFTP_MAXBUFFER];
    snprintf (buffer, NETFTP_MAXBUFFER, "%s\r\n", cmd);

    if (send (sock, buffer, strlen (buffer), 0) < 0)
    {
        MMechostr (MSKDEBUG, "net_connection_write error : not sent.\nRequest : %s", cmd);
        return -1;
    }
    return 0;
}

char* net_connection_read (SOCKET sock, NetFtpObject o)
{
    char *b = NULL;
    char z[NETFTP_MAXBUFFER];

    b = net_buffer_alloc ();
    if (recv (sock, z, sizeof (z)-1, 0) == -1)
    {
        MMechostr (MSKDEBUG, "net_connection_read error : not read\n");
        return NULL;
    }
    snprintf (b, NETFTP_MAXBUFFER, "%s", z);
    b[strlen (z)] = '\0';
    return b;
}

int net_get_XYZ (SOCKET sock, NetFtpObject o, char **reply)
{
    char *s;
    int k;

    *reply = net_connection_read (sock, o);

    s = malloc (sizeof (char)*5);
    snprintf (s, 4, "%s", *reply);
    k = atoi (s);
    free (s);
    return k;
}








#if defined _WIN32 || defined __WIN32__
void net_get_host (char *domain, char **ip)
#else
void net_get_host (char *domain, IN_ADDR *ip)
#endif
{
    struct hostent *sh;

    sh = gethostbyname (domain);
    #if ((defined linux) || (defined __linux))
    *ip = inet_ntoa (*(IN_ADDR *) sh->h_addr_list[0]); /* humm */
    #else
    *ip = inet_ntoa (*(IN_ADDR *) sh->h_addr_list[0]);
    #endif
    return;
}






#if defined _WIN32 || defined __WIN32__
int net_thread_create (int (*f) (void*, int), void* s, int flag)
{
    DWORD dwThreadId;
    HANDLE h;

    h = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) f, NULL, 0, &dwThreadId);
    if (h == NULL)
    {
        MMechostr (MSKDEBUG, "net_thread_create error : thread not created %d %s\n", errno, strerror (errno));
        return 1;
    }
    return 0;
}
#else
int net_thread_create ()
{
    return 0;
}
#endif

