/* $Id: startup.c,v 1.1 1993/11/17 12:21:51 too Exp $
 *
 * Copyright (c) 1993 AmiTCP/IP Group <amitcp-group@hut.fi>
 *
 * Created: Wed Nov 10 13:05:10 1993 too
 * Last Modified: Wed Nov 17 14:18:46 1993 too
 */
{
  struct DosPacket *	packet;
  struct DosLibrary *	l_DOSBase;
  
  SysBase = *(struct ExecBase **)4;
  
  bzero((char *)&CU, sizeof CU);
  /*
   * Give initials values to cleanup variables. The ones not mentioned
   * here are initialized to zero.
   */
  applsigbit = -1;
  NewList((struct List *)&freeappllist);
  NewList((struct List *)&writelist);
  NewList((struct List *)&freewritelist);
  
  applcbcur = 0;
  applcbpos = 0;
  
  if ((l_DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
      == NULL)
    /* in fact this cannot happen (cannot receive startup packet) */
    return 100;
  else
    /*
     * NOTE: For historical reasons returned DOSBase address will always
     *       be the same. (In future binary compatible amiga systems too)
     */
    DOSBase = l_DOSBase;

#ifdef __SASC
  mymsgport = mkDevice("TCP", 3);
#else  
  packet = WaitPkt(); /* get handler startup packet */
#endif  
  /*
   * Now try to open socket library for network communication.
   */
  if ((SocketBase = OpenLibrary("bsdsocket.library", 2)) == NULL) {
    ReplyPkt(packet, DOSFALSE, ERROR_OBJECT_NOT_FOUND);
    return clean(&CU, 20);
  }
  SetDTableSize(FD_SETSIZE);
  /*
   * Create reply port for timer message and open the timer.device.
   * The IORequest itr is filled with timer devise info that is copied
   * to each timerequest si ot can do IO with timer.device.
   */
  if (((timermsgport = CreateMsgPort()) == NULL) ||
      ((itr = AllocMem(sizeof *itr, MEMF_PUBLIC|MEMF_CLEAR)) == NULL)) {
    ReplyPkt(packet, DOSFALSE, ERROR_NO_FREE_STORE);
    return clean(&CU, 20);
  }
  
  if (OpenDevice(TIMERNAME, UNIT_VBLANK, itr, 0) != 0) {
    FreeMem(itr, sizeof *itr);
    itr = NULL; /* NULL so clean() doesn't try to close the device */
    ReplyPkt(packet, DOSFALSE, ERROR_NO_FREE_STORE);
    return clean(&CU, 20);
  }
  
  timerflag = 1 << timermsgport->mp_SigBit;
  itr->io_Command = TR_ADDREQUEST;
  itr->io_Message.mn_ReplyPort = timermsgport;
  
  /*
   * A new messageport is created for each application, but they all
   * share a common signal.
   */
  if ((applsigbit = AllocSignal(-1)) == -1) {
    ReplyPkt(packet, DOSFALSE, ERROR_NO_FREE_STORE);
    return clean(&CU, 20);
  }
  applportflag = 1 << applsigbit;
  
  /*
   * New instance startup packets comes to handler startup message
   * port (since mydev-dol_Task is set to it) I.e. this one handler
   * process is (currently) handling all new instances.
   * Data arriving to sockets are handled the usual BSD select() way.
   */
  me = FindTask(NULL);

#ifndef __SASC  
  mymsgport = &((struct Process *)me)->pr_MsgPort;
  myportflag = 1 << mymsgport->mp_SigBit;
  mydev = (struct DosList *)BADDR(packet->dp_Arg3);
  mydev->dol_Task = mymsgport;
  
  /*
   * Reply startup packet after successfull initialization.
   */
  ReplyPkt(packet, DOSTRUE, packet->dp_Arg2);
#else
  myportflag = 1 << mymsgport->mp_SigBit;
#endif
  
  /*
   * Initial settings: read and write descriptor sets are cleared,
   * nfds set to 0, indicating no sockets are created and
   * signal mask is set to listen open packets from handler user programs.
   */
  FD_ZERO(&readfds);
  FD_ZERO(&writefds);
  nfds = 0;
  sigmask = myportflag | applportflag | timerflag;
}
