/* -*- Mode: C -*-
 * $Id: gxsnmpdbc.c,v 1.10 2000/01/08 20:33:40 remlali Exp $
 * copyright:
 *
 * 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.,  59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
 *
 * API to connect and query database daemon gxdd
 *
 * think this file doesn't contain API functions
 * maybe only common functions they use ?
 *
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib.h>

#include <errno.h> /*alot junk here*/
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/un.h>
#include <netinet/in.h>   
#include <arpa/inet.h>
#include <unistd.h>

#include "g_sqldb.h"
#include "tables.h"
#include "debug.h"

#define HEADER (sizeof(gint) * 2) /* this defines how much to read in the header to retreive total packet length */

char version[] = "$Id: gxsnmpdbc.c,v 1.10 2000/01/08 20:33:40 remlali Exp $"; /*usefull to 'strings' the binary*/

/**
 * dd_read_header:
 *
 * this routine reads just as much it needs
 * on incoming data stream to determine how
 * much it has to read, ie read Total Packet Length
 *
 * RETURN:
 * good: number of bytes readed 
 * fail: -1
 *
 **/
int 
dd_read_header(int sock, char *buffer)
{
  int nbytes;
reada:
  nbytes = read(sock, buffer, HEADER);
  switch(nbytes)
    {
    case -1:
      if(errno == EAGAIN)
	{		/* nonblocking return*/
	  sleep(1);
	  goto reada;
	}
      else
	{
	  g_warning (g_strerror (errno));
	  return -1;
	}
    case HEADER:
      fprintf(stderr,"header readed!\n");
      return nbytes;
    default:			/*we guess under 3 * gint_size bytes was only available */
      return -1;
    }
}
/**
 * dd_read_rest:
 *
 **/
char *
dd_read_rest(int sock, int len, char *header)
{
  char *bulk,*blk1=0;
  int nbytes;
  int n=HEADER;
  int to = 10;
  
  
  if (!(bulk = (char *) g_malloc(len+1))) return -1;
  memcpy(bulk, header, HEADER);
  
 nodata:				       /* no data was available*/
  nbytes = read(sock, bulk+n, len-n);
  if(nbytes == (len-n)) return bulk;
  switch(nbytes)
    {
    case -1:        /*error*/
      if(errno == EAGAIN){
	sleep(1);	/*stupid, but atleast we don't eat cpu*/
	if(!(to--))
	  {
	    if(bulk) free(bulk);
	    return -1;
	  }
	goto nodata;
      }
      fprintf(stderr,"dd_read():\n");
      g_warning (g_strerror (errno));
      free(bulk);
      return -1;
    default:        /*more to read*/
      n += nbytes;
      goto nodata;
    }
}
/**
 * dd_write:
 *
 **/
int 
dd_write(int sock, int datalen, char *data)
{
  int nbytes;
  
  nbytes = write(sock, data, datalen + 1);
  if(nbytes < 0) return -1;
  return nbytes;
}

/**
 * dd_connect:
 *
 * Establish a connection to the database daemon.
 *
 **/
static struct sockaddr_in ddserver;   /* ick */

gint 
dd_connect (gchar *IP, gint port)
{
  gint     sock;
  
  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    return -1;

  ddserver.sin_family = AF_INET;
  ddserver.sin_port   = htons(port);
  ddserver.sin_addr.s_addr = inet_addr (IP);
  if (0 > connect (sock, (struct sockaddr *) &ddserver, sizeof (ddserver)))
    return -1;
  fcntl(sock, F_SETFL, O_NONBLOCK);
  return sock;
}

/**
 * dd_disconnect:
 *
 * disconnect from a database server,
 **/
void
dd_disconnect (int sock)
{
  close (sock);
}

