char RCS_ID_AUTOINIT_C[] = "$Id: autoinit.c,v 1.7 1994/02/04 01:47:09 jasegler Exp jasegler $";
/*
 * autoinit.c --- SAS C auto initialization functions
 *
 * Author: ppessi <Pekka.Pessi@hut.fi>
 *
 * Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
 *                  Helsinki University of Technology, Finland.
 *                  All rights reserved.
 *
 * Created      : Sat Mar 20 03:31:29 1993 ppessi
 * Last modified: Mon Jul 19 14:24:30 1993 jraja
 *
 */

#include <dos/dos.h>
#include <sys/types.h>
#include <devices/timer.h>
#include <exec/types.h>
#include <exec/libraries.h>

#include <intuition/intuition.h>

#ifdef __GNUC__			/* C= include files only have clib not Sux's (SASC) proto files :) */
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/socket_protos.h>
#include <signal.h>
#elif _DCC
#include <clib/socket_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#elif __SASC__
#include <proto/socket.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#endif

#include <stdio.h>
#include <stdlib.h>

struct Library *SocketBase = NULL;

int errno = 0;			/* global errno variable */

STRPTR SOCKETNAME = "bsdsocket.library";

#define SOCKETVERSION 2		/* minimum bsdsocket version to use */

#ifdef __SASC__
extern STRPTR _ProgramName;	/* SAS startup module defines this :-) */
#endif

#ifdef __GNUC__
char _ProgramName[] = "GNU C Program";
#endif

#ifdef _DCC
char _ProgramName[] = "DCC Program";
#endif

/****** amiga.lib/autoinit *********************************************

 *   NAME
 *       autoinit - SAS C Autoinitialization Functions
 *
 *   SYNOPSIS
 *       _STIopenSockets()
 *
 *       void _STIopenSockets(void)
 *
 *       _STDcloseSockets()
 *
 *       void _STDcloseSockets(void)
 *
 *   FUNCTION
 *       These functions open and close the bsdsocket.library at the
 *       startup and exit of the program, respectively. For a
 *       program to use these functions, it must be linked with
 *       netlib:net.lib.
 *
 *       If the library can be opened, the _STIopenSockets() calls
 *       bsdsocket.library function SetErrnoPtr() to tell the
 *       library the address and the size of the errno variable of
 *       the calling program.
 *
 *   NOTES
 *       _STIopenSockets() also checks that the system version is at
 *       least 37. It puts up a requester if the bsdsocket.library
 *       is not found or is of wrong version.
 *
 *       The autoinitialization and autotermination functions are
 *       features specific to the SAS C6. However, these functions
 *       can be used with other (ANSI) C compilers, too. Example
 *       follows:
 *
 *       \* at start of main() *\
 *
 *       atexit(_STDcloseSockets);
 *       _STDopenSockets();
 *
 *   BUGS
 *
 *   SEE ALSO
 *       bsdsocket.library/SetErrnoPtr(),
 *       SAS/C 6 User's Guide p. 145 for details of
 *       autoinitialization and autotermination functions.
 *****************************************************************************
 *
 */

void
_STIopenSockets (void)
{
  static short done = 0;
#ifdef __SASC__
  struct Library *IntuitionBase;
#endif
  STRPTR errorStr;

  if (done++)			/* try only once (SAS/C 6.2 liked to call this twice) */
    return;

  /*
   * Check OS version
   */
  if ((*(struct Library **) 4)->lib_Version < 37)
    exit (20);

  /*
   * Open bsdsocket.library
   */
  if ((SocketBase = OpenLibrary (SOCKETNAME, SOCKETVERSION)) != NULL)
    {
      /*
         * Succesfull. Now tell bsdsocket.library the address of our errno
       */
      SetErrnoPtr (&errno, sizeof (errno));

      return;
    }
  else
    {
      errorStr = "AmiTCP/IP version 2 or later must be started first.";
    }

#ifdef __SASC__
  IntuitionBase = OpenLibrary ("intuition.library", 36);

  if (IntuitionBase != NULL)
    {
      struct EasyStruct libraryES;

      libraryES.es_StructSize = sizeof (libraryES);
      libraryES.es_Flags = 0;
      libraryES.es_Title = _ProgramName;
      libraryES.es_TextFormat = errorStr;
      libraryES.es_GadgetFormat = "Exit %s";

      EasyRequestArgs (NULL, &libraryES, NULL, (APTR) & _ProgramName);

      CloseLibrary (IntuitionBase);
    }
  exit (20);
#endif

#ifdef __GNUC__
  fprintf (stderr, "%s\n\n", errorStr);
  exit (20);
#endif
}

void
_STDcloseSockets (void)
{
  if (SocketBase)
    {
      CloseLibrary (SocketBase);
      SocketBase = NULL;
    }
}

#ifdef __GNUC__

static void
constructor ()
{
  _STIopenSockets ();
  SetSocketSignals (SIGBREAKF_CTRL_C, SIGIO, SIGURG);
}

static void
destructor ()
{
  _STDcloseSockets ();
}

asm ("  .text;  .stabs \"___CTOR_LIST__\",22,0,0,_constructor");
asm ("  .text;  .stabs \"___DTOR_LIST__\",22,0,0,_destructor");

#endif /* GNUC Auto openers */
