/**********************************************************************
 * ti library's compatibility routine with nlist_c.c
 *
 * $Author: brlewis $
 * $Source: /mit/techinfodev/src/libti/RCS/compat.c,v $
 * $Header: /mit/techinfodev/src/libti/RCS/compat.c,v 0.3 1995/04/10 20:46:47 brlewis Exp $
 *
 * Copyright 1991 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 **********************************************************************/

#include <mit-copyright.h>

#ifndef lint
static char rcsid_ti_compat_c[] = "$Header: /mit/techinfodev/src/libti/RCS/compat.c,v 0.3 1995/04/10 20:46:47 brlewis Exp $";
#endif /* lint */

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <ctype.h>
#include <ti/memory.h>
#include <ti/ti.h>

/**********************************************************************
 * ti_compat(char *hostname, char *portname, TI **tip)
 *
 * - initializes everything for ti library
 * - assumes you have already called sweb_init()
 * - fills in TI structure
 * - returns error code
 **********************************************************************/

long
ti_compat(hostname, portname, tip)
     char *hostname, *portname;
     TI **tip;
{
  struct hostent *hp;
  extern int h_errno;
  int i, portnum;
  struct servent *sp;
  extern int sock;

  /* NULL means use default */
  if (!hostname) hostname = TI_DEF_HOST;
  if (!portname) portname = TI_DEF_PORT;

  /* initialize if this is first connection */
  if (!ti_nconnections)
    {
      init_ti_err_tbl();
      memset(ti_connections, 0, TI_MAX_OPEN * sizeof(TI));
      sigblock(sigmask(SIGPIPE)); /* XXX what about Mac, DOS? */
    }

  /* resolve hostname */
  hp = gethostbyname(hostname);
  if (hp == NULL)
    {
      /* set error context and return error code */
      strcpy(ti_context, hostname);
      switch(h_errno)
	{
	case HOST_NOT_FOUND:
	  return(TI_ERR_HOST_NOT_FOUND);
	case TRY_AGAIN:
	  return(TI_ERR_TRY_AGAIN);
	case NO_RECOVERY:
	  return(TI_ERR_NO_RECOVERY);
	case NO_ADDRESS:
	  return(TI_ERR_NO_ADDRESS);
	default:
	  return(TI_ERR_HOST);
	}
    }

  /* resolve portname */
  if (isdigit(*portname))
    portnum = htons(atoi(portname));/***/
  else
    {
      sp = getservbyname(portname, "tcp");
      if (sp == NULL)
	{
	  strcpy(ti_context, portname);
	  return(TI_ERR_UNKNOWN_PORT);
	}
      portnum = sp->s_port;
      portname = sp->s_name;
    }

  /* find TI already connected to that host and port, if one exists */
  for(i=0; i<TI_MAX_OPEN; i++)
    {
      if (!ti_connections[i].links) continue;
      if (hp->h_addrtype == ti_connections[i].sname.sin_family &&
	  portnum == ti_connections[i].sname.sin_port &&
	  !memcmp(hp->h_addr, &(ti_connections[i].sname.sin_addr),
		  hp->h_length))
	{
	  *tip = &(ti_connections[i]);
	  goto SUCCESS;
	}
    }

  /* find first free TI */
  for(i=0; i<TI_MAX_OPEN; i++)
    if (!ti_connections[i].links) break;
  if (i>= TI_MAX_OPEN)
    {
      *ti_context='\0';
      return(TI_ERR_TOOMANY);
    }
  *tip = &(ti_connections[i]);

  /* build server socket name */
  memset(&((*tip)->sname), 0, sizeof((*tip)->sname));
  (*tip)->sname.sin_family = AF_INET;
  memcpy(&(*tip)->sname.sin_addr, hp->h_addr, hp->h_length);
  (*tip)->sname.sin_port = portnum;

  /* fill in strings */
  TI_MEM((*tip)->strings = NewArray(char *, TI_STRINGS));
  memset((*tip)->strings, 0, (TI_STRINGS)*sizeof(char*));
  TI_MEM(ti_host(*tip) = newstring(hp->h_name));
  strcpy(ti_host(*tip), hp->h_name);
  TI_MEM(ti_port(*tip) = newstring(portname));
  strcpy(ti_port(*tip), portname);

  /* let the socket be the global nlist_c.c one. */
  (*tip)->sock = sock;
  ti_nconnections++;

 SUCCESS:
  /* increment reference count to this connection */
  (*tip)->links++;
  return(0L);
}
