# include <kapa_internal.h>

/** start socketed connection */
int KiiOpen (char *kii_exec, char *name) {

  int InitSocket, status;
  struct sockaddr_un Address;
  socklen_t AddressLength;
  char temp[128], socket_name[64];
  int Ntry, fd;

  sprintf (socket_name, "/tmp/Kii.XXXXXX");
  if ((fd = mkstemp (socket_name)) == -1) {
    fprintf (stderr, "error starting kii\n");
    return (-1);
  }
  close (fd);
  unlink (socket_name);

  strcpy (Address.sun_path, socket_name); 
  Address.sun_family = AF_UNIX; 
  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
  status = bind (InitSocket, (struct sockaddr *) &Address, sizeof (Address));
  status = listen (InitSocket, 1);
  
  if (name == NULL) {
    sprintf (temp, "%s %s &", kii_exec, socket_name);
  } else {
    sprintf (temp, "%s %s -name %s &", kii_exec, socket_name, name);
  }
  system (temp);

  AddressLength =  sizeof (Address);
  fcntl (InitSocket, F_SETFL, O_NONBLOCK); 

# define NTRY 500
  Ntry = 0;
  while (Ntry < NTRY) {
    fd = accept (InitSocket, (struct sockaddr *)&Address, &AddressLength);
    if (fd != -1) break;
    if (errno != EAGAIN) break;
    usleep (10000);
    Ntry ++;
  }

  if (fd < 0) return (-1);

  fcntl (fd, F_SETFL, !O_NONBLOCK); 
  return (fd);
}

int KiiWait (char *sockpath) {

  int sock, status;
  struct sockaddr_un Address;

  strcpy (Address.sun_path, sockpath);
  Address.sun_family = AF_UNIX;
  sock = socket (AF_UNIX, SOCK_STREAM, 0);
  status = connect (sock, (struct sockaddr *) &Address, sizeof (Address));
  if (status < 0) {
    fprintf (stderr, "unsuccessful connection: %d\n", status);
    exit (0);
  }
  fcntl (sock, F_SETFL, O_NONBLOCK);  
  unlink (sockpath);
  return (sock);
}

int KiiClose (int fd) {

  if (fd < 1) return (FALSE);
  KiiSendCommand (fd, 4, "QUIT");
  close (fd);
  return (TRUE);
}
