/* 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, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, 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
   Modified Jan 1996 by Eberhard Mattes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <ctype.h>
#include <unistd.h>
#include <os2.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/emxload.h>
#include <netdb.h>
#include <netinet/in.h>


void socket_to_stdout (void *arg)
{
  int s, nread;
  ULONG nwritten, rc;
  static char buf[4096];

  s = *(int *)arg;
  while ((nread = recv (s, buf, sizeof (buf), 0)) > 0)
    {
      rc = DosWrite (1, buf, (ULONG)nread, &nwritten);
      if (rc != 0)
        {
          fprintf (stderr, "DosWrite(): rc=%lu\n", rc);
          break;
        }
      if (nwritten != (ULONG)nread)
        {
          fputs ("DosWrite(): Message truncated\n", stderr);
          break;
        }
    }
  if (nread == -1)
    perror ("recv()");
}


void stdin_to_socket (void *arg)
{
  int s, nwritten;
  ULONG rc, nread;
  static char buf[4096];

  s = *(int *)arg;
  while ((rc = DosRead (0, buf, sizeof (buf), &nread)) == 0)
    if ((nwritten = send (s, buf, nread, 0)) != nread)
      {
        if (nwritten == -1)
          perror ("send()");
        else
          fputs ("send(): Message truncated\n", stderr);
        break;
      }
  if (rc != 0)
    fprintf (stderr, "DosRead(): rc=%lu\n", rc);
}


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;
    }

  _emxload_this (10*60);

  hostname = argv[1];
  if (argc >= 3)
    service = argv[2];
  else
    service = "nntp";

  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;
    }

  host = gethostbyname (hostname);
  if (host == NULL)
    {
      fprintf (stderr, "gethostbyname failed\n");
      return EXIT_FAILURE;
    }

  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");
      close (server);
      return EXIT_FAILURE;
    }

  _beginthread (stdin_to_socket, 0, 0x100000, &server);
  socket_to_stdout (&server);

  close (server);
  return EXIT_SUCCESS;
}
