/* TCP/IP stream emulation for GNU Emacs.
   Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.

This file is part of GNU Emacs.

GNU Emacs 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, or (at your option)
any later version.

GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

/* Rewritten for OS/2 2.x & IBM TCP/IP by Richard Krehbiel (richk@netcom.com)
   Modified for 32-bit IBM TCP/IP 2.0 by Todd Scalzott (scalzott@netcom.com)
   Rewritten Jun 1994 by Eberhard Mattes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <ctype.h>
#include <os2.h>
#include "tcp.h"


void socket_to_stdout (void *arg)
{
  int s;
  ULONG nread, nwritten;
  static char buf[4096];

  s = *(int *)arg;
  while ((nread = recv (s, buf, sizeof (buf), 0)) > 0)
    DosWrite (1, buf, nread, &nwritten);
}


void stdin_to_socket (void *arg)
{
  int s;
  ULONG nread;
  static char buf[1024];

  s = *(int *)arg;
  while (DosRead (0, buf, sizeof (buf), &nread) == 0)
    send (s, buf, nread, 0);
}


int main (int argc, char *argv[])
{
  struct sockaddr_in sockin, sockme;
  struct hostent *host;
  struct servent *serv;
  char *hostname, *service;
  int server, i;
  u_short port;

  if (argc < 2 || argc > 3)
    {
      fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
      return EXIT_FAILURE;
    }

  hostname = argv[1];
  if (argc >= 3)
    service = argv[2];
  else
    service = "nntp";

  host = gethostbyname (hostname);
  if (host == NULL)
    {
      fprintf (stderr, "gethostbyname failed\n");
      return EXIT_FAILURE;
    }

  if (isdigit (service[0]))
    port = htons (atoi (service));
  else
    {
      serv = getservbyname (service, "tcp");
      if (serv == NULL)
        {
          fprintf (stderr, "getservbyname failed\n");
          return EXIT_FAILURE;
        }
      port = serv->s_port;
    }

  memset (&sockin, 0, sizeof (sockin));
  sockin.sin_family = host->h_addrtype;
  memcpy ((caddr_t)&sockin.sin_addr, host->h_addr, host->h_length);
  sockin.sin_port = port;

  server = socket (AF_INET, SOCK_STREAM, 0);
  if (server < 0)
    {
      fprintf (stderr, "socket failed\n");
      return EXIT_FAILURE;
    }

  i = 0;
  if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR,
                  (char *)&i, sizeof (i)) != 0)
    {
      fprintf (stderr, "setsockopt failed\n");
      return EXIT_FAILURE;
    }

  memset (&sockme, 0, sizeof (sockme));
  sockme.sin_family = sockin.sin_family;
  sockme.sin_addr.s_addr = INADDR_ANY;
  if (bind (server, (struct sockaddr *)&sockme, sizeof (sockme)) < 0)
    {
      fprintf (stderr, "bind failed\n");
      return EXIT_FAILURE;
    }

  if (connect (server, (struct sockaddr *)&sockin, sizeof (sockin)) < 0)
    {
      fprintf (stderr, "connect failed\n");
      soclose (server);
      return EXIT_FAILURE;
    }

  i = 0;
  soioctl (server, FIONBIO, (char *)&i, sizeof (i));
  
  _beginthread (stdin_to_socket, 0, 0x8000, &server);
  socket_to_stdout (&server);

  soclose (server);
  return EXIT_SUCCESS;
}
