/*   GET.C     Client for Peter/Pete's IPC system.        bjw  june 88 */

/*
//              This client requests the function of multiplication:
//              You pass two numbers, the result is their product.  This is
//              meant to be a pseduo-test suite for the Manx IPC product.
//              Reads numbers from command line only.
//
//              bjw             25-june-88      Initial coding.
//              Pete G.         4-aug-88        Revisions
//
//  [In my capacity as "editor", I've taken the liberty of making several
//   changes in Brian's original, for various necessary reasons.  I hope
/    he'll forgive me.   -- Pete --]
*/


#include <exec/types.h>

#include "IPC.H"

#include <stdio.h>

#ifdef AZTEC_C
#include <functions.h>
#endif

#define  VERSION    "0.02"
#define  IPC_NAME   "MULT"

#define  ID_NUMBER  MAKE_ID('N','U','M','B')

extern long  atol ();


/* ---------------------  Global Variables  -------------------------- */


struct IPCPort   *port;                       /* Our point of service */
struct MsgPort   *reply;


/* ----------------------  Primitive Code  --------------------------- */

fillItem (item, number)
        struct IPCItem  *item;
        long   number;
{

        item->ii_Id = ID_NUMBER;
        item->ii_Flags = IPC_TRANSFER | IPC_NETWORK;
        item->ii_Size = 0;
        item->ii_Ptr = (void *) number;
}


/* ---------------------  The Code Beginneth  ------------------------ */

/*
 *  This procedure sends a single message
 */
        long
send (str1, str2)
        char  *str1, *str2;
{
        register struct IPCMessage   *msg;
        long   n1, n2;
        long   res;

        n1 = atol (str1);
        n2 = atol (str2);

        msg = CreateIPCMsg (3, 0, reply);
        if (!msg) return -1;

        msg->ipc_Items[0].ii_Size = 0;          /* Server provides result here */
        fillItem (& msg->ipc_Items[1], n1);
        fillItem (& msg->ipc_Items[2], n2);

        if (PutIPCMsg (port, msg)) /* MUST always check that it got sent! */
            WaitPort (reply);               /* Get the reply */

        if (((msg->ipc_Flags & IPC_NOTKNOWN) == 0) &&
                (msg->ipc_Items[0].ii_Flags & IPC_MODIFIED) )
        {
                res = (long) msg->ipc_Items[0].ii_Ptr;
        } else
        {
                res = -1;
        }

        DeleteIPCMsg (msg);

        return (res);
}       /* send */


void Getout(exitcode) int exitcode;
{
    if (port) DropIPCPort(port);
    if (reply) DeletePort(reply);
    exit(exitcode);
}



main (argc, argv)
        int  argc;
        char *argv[];
{
        long   res;

        fprintf (stderr, "[Use %s, %s]\n", IPC_NAME, VERSION);

        if (argc != 3)
        {
                fprintf (stderr, "usage: get <numb1> <numb2>\n");
                fprintf (stderr, "\tprint product of two numbers\n");
                exit (1);
        }

        port = FindIPCPort (IPC_NAME);
        /* [In most cases GetIPCPort is preferable, so that you don't
            have to have a server already loaded, but this client sends
            its message the moment it is called, so FindIPCPort is
            appropriate   -- Pete --]
        */
        if (port == NULL)
        {
                fprintf (stderr, "Can't find server.\n");
                Getout(1);
        }

        reply = CreatePort (0L, NULL);
        if (!reply) Getout(1);

        res = send (argv[1], argv[2]);

        printf ("%s (%s,%s) --> %ld\n", IPC_NAME, argv[1], argv[2], res);

        Getout(0);

}       /* main */
