/* This file is part of XgIRC 0.1
   sockets.c - Network-related functions

   Copyright (C) 1998 A|vin (Julien Pieraut) <alvin@another-world.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <strings.h>
#include <errno.h>
#include <signal.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include "main.h"
#include "sockets.h"
#include "display.h"

/* ========================================================================== *
 * = Resolves ip of hostname 'name' (ripped)                                = *
 * ========================================================================== */
struct in_addr
resolv (char *name)
{
  static struct in_addr in;
  unsigned long l;
  struct hostent *ent;

  if ((l = inet_addr (name)) != INADDR_NONE)
    {
      in.s_addr = l;
      return in;
    }
  if (!(ent = gethostbyname (name)))
    {
      in.s_addr = INADDR_NONE;
      return in;
    }
  return *(struct in_addr *) ent->h_addr;
}

/* ========================================================================== *
 * = Sends 'string' to socket s - Returns 1 if success, 0 otherwise         = *
 * ========================================================================== */
int
sendln (int s, char *string)
{
  if (!red_led2)
    {
	  gtk_pixmap_set (GTK_PIXMAP(red2_pixmapwid), red_on_pixmap, red_on_pixmapm);
      red_led2 = gtk_timeout_add (LEDS_LIT_DURATION, reset_led2, NULL);
    }
  else
    {
      gtk_timeout_remove (red_led2);
      red_led2 = gtk_timeout_add (LEDS_LIT_DURATION, reset_led2, NULL);
    }
#ifdef DEBUG
  g_print ("[D] To socket %d : %s <sockets.c/sendln>", s, string);
#endif
  strcat (string, "\n");
  if (send (s, string, strlen (string), 0x0) < 0)
    {
#ifdef DEBUG
     g_print (" [ERROR]\n");
#endif
      return (0);
    }
#ifdef DEBUG
  g_print (" [OK]\n");
#endif
  return (1);
}

/* ========================================================================== *
 * = Reads 'buf' from sock s - Returns 1 if success, 0 otherwise (ripped)   = *
 * ========================================================================== */
int
readln (int s, char *buf)
{
  int to = 0;
  char c;
  if (!red_led1)
    {
	  gtk_pixmap_set (GTK_PIXMAP(red1_pixmapwid), red_on_pixmap, red_on_pixmapm);
      red_led1 = gtk_timeout_add (LEDS_LIT_DURATION, reset_led1, NULL);
    }
  else
    {
      gtk_timeout_remove (red_led1);
      red_led1 = gtk_timeout_add (LEDS_LIT_DURATION, reset_led1, NULL);
    }
  do
    {
      if (read (s, &c, 1) < 1)
	return (0);
      if (c != 10) { /* LF */
		  if ((c >= ' ') || (c <= 126))
			  if (to < MAXLEN)
				  buf[to] = c;
          else buf[to] = ' ';
		  to++;
	  }
	}
  while (c != '\n');
if (buf[to-1]==13) buf[to -1] = '\0';
else buf[to]='\0';
#ifdef DEBUG
  g_print ("[D] From socket %d : %s <sockets.c/readln>\n", s, buf);
#endif
  return (1);
}

/* ========================================================================== *
 * = Opens a socket to 'host' 'port' - Returns the socket's fd, -1 if error = *
 * ========================================================================== */
int
open_socket (char *host, int port)
{
  struct sockaddr_in addr;
  int i;

#ifdef DEBUG
  g_print ("[D] Opening connection to %s:%i... <sockets.c/open_socket>", host, port);
#endif
  s = socket (AF_INET, SOCK_STREAM, 0);
  addr.sin_family = AF_INET;
  addr.sin_addr = resolv (host);
  addr.sin_port = htons (port);
  if (connect (s, (struct sockaddr *) &addr, sizeof (addr)) > -1)
    {
#ifdef DEBUG
     g_print (" [OK]\n");
#endif
      return (s);
    }
#ifdef DEBUG
 g_print (" [ERROR]\n");
#endif
  return (-1);
}
