/* $Id: sender.c,v 1.4 1993/08/06 08:59:59 jraja Exp $
 *
 * sender.c --- letnet sender code
 *
 * Author: Pekka Pessi <Pekka.Pessi@hut.fi>
 *
 * Copyright (c) 1993 Pekka Pessi
 *                    All rights reserved
 *
 * Created      : Tue Mar 23 20:10:33 1993 ppessi
 * Last modified: Mon May 24 05:54:55 1993 ppessi
 *
 * $Log: sender.c,v $
 * Revision 1.4  1993/08/06  08:59:59  jraja
 * Changed required bsdsocket.library version to 2.
 *
 * Revision 1.3  1993/05/26  23:45:32  ppessi
 * Experiment with pr_ExitCode; some resource allocation bugs fixed.
 *
 * Revision 1.2  1993/05/23  17:57:57  ppessi
 * Changed ID handling.
 *
 * Revision 1.1  93/05/18  00:59:07  ppessi
 * Initial revision
 * 
 */

#define SocketBase childSocketBase

struct Library *childSocketBase;

#ifdef AMIGA
#if __SASC
#include <proto/dos.h>
#include <clib/exec_protos.h>
#include <pragmas/exec_pragmas.h>
#include <proto/socket.h>
#elif __GNUC__
#include <inline/socket.h>
#include <inline/exec.h>
#else
#include <clib/socket_protos.h>
#endif
#endif /* AMIGA */

#include <errno.h>
#include <netdb.h>

#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>

#include <signal.h>

#include <dos/dos.h>
#include <exec/execbase.h>
#include <exec/memory.h>

#include "letnet.h"

SAVEDS ASM LONG exitcode(REG(d0) LONG status, REG(d1) LONG exitmessage)
{
  ((struct SocketMessage *)exitmessage)->sm_retval = status;
  ReplyMsg((struct Message *)exitmessage);
}

int
sender(int s)
{
  int m = 0, n = 0, istty;
  int retval = 0;
  char *cb = NULL;

  BPTR InFh = Input();

  if (InFh) {
    cb = AllocMem(SENDBUFLEN, MEMF_PUBLIC);
    if (!cb) {
      PrintNetFault(Errno(), "Sender");
      retval = 2;
      goto Return;
    }

    istty = IsInteractive(InFh);

    do {
      if (SetSignal(0L, 0L) & SIGBREAKF_CTRL_C) goto Return;
      
      if (istty) {
	/* Wait a char for a second */
	if (!WaitForChar(InFh, 1000000)) continue;
	n = 1;
      } else { 
	n = SENDBUFLEN;
      }

      m = Read(InFh, cb, n);

      if (m == -1) {
	PrintFault(IoErr(), "Read");
	retval = 2;
	goto Return;
      }

      if (send(s, cb, m, 0) != m) {
	PrintNetFault(Errno(), "send");
	retval = 2;
	goto Return;
      }
    } while(m == n);		/* DOS EOF from Read() */
  }

 Return:
  shutdown(s, 1);		/* no more sends */
  if (cb) FreeMem(cb, SENDBUFLEN);

  return retval;
}

/* 
 * This is generic daemon startup code
 */
SAVEDS LONG
do_sender(void) 
{
  int s;
  int retval = 1;

  struct SocketMessage *exitm = (struct SocketMessage*)
    ((struct Process*)FindTask(NULL))->pr_ExitData; 

  if (SocketBase = OpenLibrary("bsdsocket.library", 2L)) {
    s = ObtainSocket(exitm->sm_id, PF_INET, SOCK_STREAM, NULL);
    if (s != -1) {
      retval = sender(s);
    } else {
      PrintNetFault(Errno(), "ObtainSocket");
    }
    CloseLibrary(SocketBase);
  }

  Flush(Output());
  return retval;
}

