/*
**  CLIExchange : Gael Marziou
**
**  A simple CLI replacement for standard utility Exchange
**  Without any argument it applies the command specified to
**  all running commodities.
**  Arguments must be a list of Commodities.names
**  Names are case sensitive.
**  Of course, it is a 2.04 only command.
**
**	Compiled with SAS C 6.50
**
**  1.0: 15 Jan. 1994, first release, size = 688 bytes
**  1.1: 19 Jan. 1994, size = 672 bytes
**  1.2: 20 Jan. 1994, size = 592 bytes
*/


#include <dos/dos.h>
#include <exec/exec.h>
#include <libraries/commodities.h>
#include <string.h>

#include <clib/alib_protos.h>
#include <clib/commodities_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

#ifdef __SASC
#   define __USE_SYSBASE
#   include <pragmas/commodities_pragmas.h>
#   include <pragmas/dos_pragmas.h>
#   include <pragmas/exec_pragmas.h>
#endif

UBYTE *version = "$VER: CLIExchange 1.2 (1.20.94)";

#define TEMPLATE  "KILL/S,ENABLE/S,DISABLE/S,APPEAR/S,DISAPPEAR/S,UNIQUE/S,CXNAME/M"

#define OPT_KILL  		0
#define OPT_ENABLE		1
#define OPT_DISABLE		2
#define OPT_APPEAR 		3
#define OPT_DISAPPEAR 	4
#define OPT_UNIQUE		5
#define OPT_CXNAME  	6
#define OPT_COUNT 		7


/****************************************************/
/* The following definitions have been found in the */
/* source of MUI-Exchange written by Klaus Melchior */
/****************************************************/

/***  private functions of "commodities.library"  ***/

#pragma libcall CxBase FindBroker 6c 801
#pragma libcall CxBase CopyBrokerList ba 801
#pragma libcall CxBase FreeBrokerList c0 801
#pragma libcall CxBase BrokerCommand c6 802

CxObj *FindBroker(char *);
LONG CopyBrokerList(struct List *);
LONG FreeBrokerList(struct List *);
LONG BrokerCommand(char *, LONG id);


/*** private structures & defines ***/

struct BrokerCopy	{
	struct Node	bc_Node;
	char	bc_Name[CBD_NAMELEN];
	char	bc_Title[CBD_TITLELEN];
	char	bc_Descr[CBD_DESCRLEN];
	LONG	bc_Task;
	LONG	bc_Dummy1;
	LONG	bc_Dummy2;
	UWORD	bc_Flags;
};



ULONG
CLIExchange(void)
{
    struct Library    *CxBase;
    struct DosLibrary *DOSBase;
    ULONG  rc = RETURN_FAIL;
	UBYTE  i;
	LONG   opts[OPT_COUNT];
    LONG   Command;
    struct RDArgs *rdargs;
    char  *curarg, **argptr;
    struct List *l;
    struct Node *n, *nn;
    UBYTE  OptCommand[OPT_CXNAME] =
    {
        CXCMD_KILL,
        CXCMD_ENABLE,
        CXCMD_DISABLE,
        CXCMD_APPEAR,
        CXCMD_DISAPPEAR,
        CXCMD_UNIQUE
	};


    /* Before bothering with anything else, open the libraries we need */
    DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L);
	CxBase = OpenLibrary("commodities.library", 37L);

	if (CxBase && DOSBase)
	{
		/* Clear the options array, just to be on the safe side... */
		memset((char *)opts, 0, sizeof(opts));

		/* Parse the command line. */
		rdargs = ReadArgs(TEMPLATE, opts, NULL);
            
		if (rdargs == NULL)
		{
			PrintFault(IoErr(), NULL);
		}
		else
		{
			rc = RETURN_OK;
					
			/* Find which option has been set by user */
			i = OPT_KILL;
			while (!opts[i] && (i<OPT_CXNAME))
			{
				i++;
			}
			if (i < OPT_CXNAME)
			{
				Command = OptCommand[i];
			}

			/* Initialize for MultiArgs handling */
			argptr = (char **)opts[OPT_CXNAME];
                
			if ((argptr == NULL) || (i == OPT_CXNAME))
			{
				/* no commodities names means ALL commodities */

				if (l = AllocVec(sizeof(struct List),MEMF_PUBLIC)) 
				{
					NewList(l);
					CopyBrokerList(l);

					for (n = l->lh_Head; n && (nn = n->ln_Succ); n = nn)
					{
                        if (i == OPT_CXNAME)
                        {
                            Printf("%s\n",(char *)((struct BrokerCopy *)n)->bc_Name);
                        }
                        else
                        {
                            BrokerCommand((char *)((struct BrokerCopy *)n)->bc_Name, 
                                          Command);
                        }
                    }
                    FreeBrokerList(l);
                    FreeVec(l);
                }
            }
            else
            {
                /* The following while loop handles the MultiArgs spec. */
                        
                while (curarg = *argptr++)
                {
                    BrokerCommand ((char *)curarg, Command);
                }      
            }
        }
    }   
    CloseLibrary(CxBase);
    CloseLibrary((struct Library *)DOSBase);
    return(rc);
}





