/* Copyright (c) 2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdarg.h>

#include "japi.h"

/* connect to server.  return socket descriptor */
int
do_connect(char *hostname, int portnum)
{
  static struct hostent *hp;
  static struct sockaddr_in sin;
  int sd;

  /* get host entry */
  if ((hp = gethostbyname(hostname)) == NULL) {
    fprintf(stderr, "Error: host \"%s\" not found\n", hostname);
    exit(1);
  }
  /* open socket */
  memset((char *)&sin, 0, sizeof(sin));
  memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
  sin.sin_family = hp->h_addrtype;
  sin.sin_port = htons(portnum);
  if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    perror("Error: socket()");
    exit(1);
  }
  /* connect */
  fprintf(stderr, "connecting to %s:%d...", hostname, portnum);
  if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
    perror("Error");
    exit(1);
  }
  fprintf(stderr, "done\n");
  return(sd);
}

/* disconnect */
void
do_disconnect(int sd)
{
  if (close(sd) < 0) {
    fprintf(stderr,"Error: close() failed");
  }
}

/* send data to server (with printf format) */
void
do_sendf(int sd, char *fmt, ...)
{
  static char buf[MAXLINELEN];
  va_list ap;
  int n;
  
  va_start(ap, fmt);
  vsnprintf(buf, MAXLINELEN, fmt, ap);
  n = write(sd, buf, strlen(buf));
  if (n < 0) {
    perror("Error: do_sendf");
  }
  va_end(ap);
}

/* send data to server */
void
do_send(int sd, char *buf)
{
  int n;
  
  n = write(sd, buf, strlen(buf));
  if (n < 0) {
    perror("Error: do_send");
  }
}

/* reveive data from server (return at newline or EOM) */
/* strip newline */
/* return pointer to buf, or NULL on error */
char *
do_reveive(int sd, char *buf, int maxlen)
{
  int cnt;
  char *p;
  
  p = buf;
  while(1) {
    cnt = read(sd, p, 1);
    if (cnt <= 0) return NULL;		/* eof or error */
    if (*p == '\n' && p > buf) {
      *p = '\0';
      break;
    } else {
      if (++p >= buf + maxlen) {
	fprintf(stderr,"Error: do_receive: line too long (> %d)\n", maxlen);
	exit(1);
      }
    }
  }
  return buf;
}
