
/*
 * FAME DoorConfig Door
 * ~~~~~~~~~~~~~~~~~~~~
 *
 * $VER: FAMEDoorConfig.c v1.1
 *
 * FAMEDoorConfig.FIM is a non-FIM DoorConfig starter door.
 *
 * Code by: David 'Strider/tRSi' Wettig
 * E-Mail:  strider@trsi.de
 * URL:     http://www.trsi.de/inno/strider/index.html
 *
 * Used tab size: 2
 */

/*
 * Includes:
 */

#include <FAME/FAMEPublic.h>

/*
 * Disable Lattice CTRL-C handling:
 */

#ifdef LATTICE
int CXBRK(void) {return(0);}
int chkabort(void) {return(0);}
#endif

/*
 * Define our version string for the "version" command:
 */

char *VerStr = {"$VER: FAMEDoorConfig.FIM v1.1 "__AMIGADATE__};

/*
 * _ProgramName contains our filename:
 */

extern char	*_ProgramName;

/*
 * Prototypes:
 */

void ShutDown( long ErrCode );

/*
 * No CON window please, quit immediately.
 */

void __autoopenfail(void) { _XCEXIT(0);}

/*
 * Variables for ReadArgs and Template.
 */

char 	ArgStr[]		= "NODENR/N/A";
long	ArgArray[]	= {0L};

/*
 * Global variables:
 */

struct FAMELibrary	*FAMEBase			= NULL;

/*
 * void main( void );
 *
 * main() entry point:
 */

void main( void )
{
	struct  RDArgs	*rda						= NULL;
	long						NodeNr;
	char						WorkStr[256],
									WorkBuf[256];
	STRPTR					MyStrPtr				= NULL;

	/*
	 * Use ReadArgs() for arguments:
	 */

	if(rda = ReadArgs(ArgStr,ArgArray,NULL))
	{
		/*
		 * Read the Node number:
		 */

		if(ArgArray[0])
		{
			long *LDummy = (long *)ArgArray[0];
			NodeNr = (*LDummy);
		}

		FreeArgs(rda);
	}
	else
	{
		/*
		 * Something failed with the argument, exit the door:
		 */

    Printf("\nSorry, %s is a Door and must be called from FAME BBS!\n\n",_ProgramName);

		SetIoErr( ERROR_REQUIRED_ARG_MISSING );
		PrintFault(IoErr(),"FAMEDoorConfig.FIM");

    exit( RETURN_FAIL );
  }

	/*
	 * Now we have to open the FAME.library.
	 *
	 * From now on we have to call our ShutDown() function if something fails
	 * on our own resource initialisation where we have to release all our
	 * Door resources in ShutDown(). We are allowed to use ShutDown() just to
	 * the point where we call FIMStart(). From then we *HAVE* to call
	 * FIMEnd(0) to end the door!
	 *
	 * FIMEnd(0) will do our ShutDown() call then for us.
	 */

	if( ! (FAMEBase = (struct FAMELibrary *) OpenLibrary("FAME.library",0L)))
	{
		ShutDown( RETURN_FAIL );
	}

	/*
	 * Ok time to continue with the Door initialisation code.
	 *
	 * Now we have to build the MessagePort name string of the Door we
	 * are called from:
	 */

  SPrintf(FAMEDoorPort,"FAMEDoorPort%ld",NodeNr);

	/*
	 * Now we start the Door initialising code.
	 *
	 * Here we can define the buffer size for the Global String Pointer
	 * if we need more than the default of 1024 bytes. If we call FIMEnd()
	 * with a value < 1024 bytes (FIM_MINBUFSIZE) like here (0) FIMStart()
	 * will use automatically the default value of FIM_MINBUFSIZE (1024 bytes).
	 *
	 * With the second argument we can set some flags we might need for our
	 * Door to tell the FIM DoorStartUp code how to handle some things we
	 * need. Following flags are available (bit-flags you can combine them by
	 * separating them with the OR sign: |
	 * i.e.: FIMF_USERSIGMODE | FIMF_NOCHECK.
	 *
	 * - FIMF_USERSIGMODE to enable the user signal check.
	 * - FIMF_NOCHECK to disable the error check of FIM commands send to
	 *   the door. Some doors might need to continue work also if there is
	 *   a problem with the port or a command like a lost carrier.
	 *   If FIMF_NOCHECK is set *YOU* have to check the return code of the
	 *   support commands you are using yourself!
	 *
	 * Example: (FIM_CMDSUCCESSFULL = 0)
	 *
	 * if(GetString(StrBuffer,50) < FIM_CMDSUCCESSFULL)
	 * {
	 *   ...
	 *
	 *   FIMEnd(0);
	 * }
	 *
	 *
	 * From now on you *HAVE* to call FIMEnd(0) to end the door!
	 * FIMEnd(0) calls the from the door supported function ShutDown() itself.
	 * This is also the reason why if FIMStart() fails no longer ShutDown()
	 * will be called from here. FIMStart() has already called it if something
	 * failed during the Door initialisation so if FIMStart() fails just
	 * exit() is needed here:
	 */

  if(FIMStart( 0, 0UL ))
	{
		exit( RETURN_ERROR );
	}

  /*
	 * Place your own code in here:
	 */

	// ****************************************************************

	/*
	 * Version check:
	 */

	GetCommand(WorkStr,0,0,0,SR_FAMEVersion);

	if(MyFAMEDoorMsg -> fdom_Data2 < 1 || (MyFAMEDoorMsg -> fdom_Data2 == 1 && MyFAMEDoorMsg -> fdom_Data3 < 13))
	{
		PutString("\r\n[33mSorry[m, [33myou need at least MainPart v[33m1[m.[33m13 to use FAMEDoorConfig.FIM v[33m1[m.[33m1 [m!",1);

		Delay( 100 );

		/*
		 * End the Door:
		 */

		FIMEnd( FIM_USERERROR + 1 );
	}

	/*
	 * Get the Door arguments:
	 */

	GetCommand(WorkStr,0,0,0,NR_MainLine);

	/*
	 * Get name and arguments:
	 *
	 * First part string is the new DoorCallName and the rest it's arguments.
	 */

	/*
	 * Find the first space:
	 */

	if(MyStrPtr = FAMEStrChr(WorkStr,' '))
	{
		/*
		 * Go to the char behind the space if there is one and get the rest string:
		 */

		MyStrPtr ++;

		if(MyStrPtr)
		{
			strcpy(WorkBuf,MyStrPtr);
		}
		else
		{
	    WorkBuf[0] = '\0';
	  }

		/*
		 * Go back to our space:
		 */

		MyStrPtr --;

		/*
		 * Overwrite the sapce with a 0-byte to cut it here, so we have the name:
		 */

		(*MyStrPtr) = '\0';

	}
	else
	{
    WorkBuf[0] = '\0';
  }

	MyFAMEDoorMsg->fdom_StringPtr = WorkBuf;

	/*
	 * Start the foreign DoorConfig door from the full argument as SYSCMD:
	 */

	PutCommand(WorkStr,-2,0,0,CF_SpecialCmd);

	// ****************************************************************

	/*
	 * End the Door:
	 */

	FIMEnd(0);

} // void main( void );

/*
 * void ShutDown( long ErrCode );
 *
 * This function has to be supplied by the door and will be called if any
 * error occures. It's up to the door to exit or continue the work, but
 * remember that the DoorPort and therefor the communication to FAME is
 * CLOSED ! The errcode contains the errorcode supplied by FAME, you may
 * use it to your own requirements.
 */

void ShutDown( long ErrCode )
{
	/*
	 * Now close the FAME.library.
	 *
	 * First check if the resource is really allocated:
	 */

	if(FAMEBase)
	{
		CloseLibrary((struct Library *)FAMEBase);
	}

	/*
	 * To NULL our pointers after freeing the resource of it is *VERY*
	 * important to avoid problems if ShutDown() gets called more the one time!
	 */

	FAMEBase = NULL;

	/*
	 * Now do some standard AmigaOS error handling if needed:
	 */

	if(ErrCode < RETURN_OK )
	{
		SetIoErr( ERROR_OBJECT_NOT_FOUND );
		PrintFault(IoErr(),"FAMEDoorConfig.FIM");

		ErrCode = RETURN_ERROR;
	}

	/*
	 * Exit the Door with a standard and defined AmigaOS exit code:
	 */

	exit( ErrCode );

} // void ShutDown( long ErrCode );

/*
 * void UserSigHandle( ULONG UserSigs );
 *
 * This function has to be supplied by the door and will be called if any
 * user signal occures. User signals will be set via FIMHandlePort() in the
 * second argument "ULONG UserSigs". Use NULL here if you don't have any
 * signals to be supported. UserSigHandle() will be called if any user
 * signals are set and if FIMHandlePort() receives them. In this case
 * check the argument "UserSigs" in your UserSigHandle() function.
 *
 * You can also use the global variable "GlobUserSigs" to inform
 * FIMHandlePort() about your own additional signal bits.
 * In this case FIMHandlePort()'s second argument "ULONG UserSigs" has to
 * be always NULL, because this argument has the higher priority and
 * "GlobUserSigs" will not be used then.
 * "GlobUserSigs" is to handle your own signal bits more easy.
 * All support functions will pass NULL to FIMHandlePort() so usage of
 * "GlobUserSigs" is possible without doing any changes to the doorstartup
 * code.
 *
 *
 * FAMEDoorConfig.FIM needs no user signals so UserSigHandle() will just return.
 *
 * It's only implemented for FAMEDoorStartUp codes compiled with the
 * FIM_USERSIGMODE define.
 */

#ifdef FIM_USERSIGMODE

void UserSigHandle( ULONG UserSigs )
{
	// Do nothing - just return.

} // void UserSigHandle( ULONG UserSigs );

#endif

