/********************************************************************
 *                                                                  *
 *                 LoadIPCPort module 88:7:22                       *
 *                                                                  *
 ********************************************************************/

#include "IPCPorts.h"
#include "IPC.h"

#define IPPL MAKE_ID('I','P','P','L')
#define PORT MAKE_ID('P','O','R','T')

extern struct IPCBasePort *IPCBasePort;

/*
 *  LoadIPCPort
 *
 *     Gets an IPCPort of the specified name.  If it is not already
 *     being served or had a server being loaded, a message is sent
 *     to IPCBasePort (if IT has a server) requesting that a server
 *     be supplied.
 *     If, when the message is replied, the port is flagged as served
 *     or being loaded, the port pointer is returned. If no server is
 *     available, it drops the port again and returns NULL.
 */

struct IPCPort * LoadIPCPort(name) char *name;
{
    struct IPCPort *port=NULL,
                   *RPort = NULL;
    struct IPCMessage *mesg = NULL;
    struct IPCItem *item;

    port = GetIPCPort(name);
    if (!port) return NULL;
    if (port->ipp_Flags & (IPP_SERVED | IPP_LOADING))
        return port;
    if ((RPort = ServeIPCPort(NULL)) /* only a replyport really */
            && (mesg = CreateIPCMsg(1L, 0L, (struct MsgPort *)RPort))) {
        mesg->ipc_Id = IPPL;
        item = mesg->ipc_Items;
        item->ii_Id = PORT;
        item->ii_Ptr = (void *)port;
        if (PutIPCMsg((struct IPCPort *)IPCBasePort, mesg)) {
            WaitPort(RPort);
            GetMsg(RPort);
        }
    }
    if (RPort) LeaveIPCPort(RPort);
    if (mesg) DeleteIPCMsg(mesg);
    if (port->ipp_Flags & (IPP_SERVED | IPP_LOADING))
        return port;
    DropIPCPort(port);
    return NULL;
}


