/**
  * Create a unary tuple containing the given element.
  *
  * @param elem
  *                the element to create the tuple from.
  *
  * @exception java.lang.IllegalArgumentException
  *                    if the element is null.
  */
 public OtpErlangTuple(OtpErlangObject elem)
 {
     if (elem == null)
     {
         throw new ArgumentException("Tuple element cannot be null");
     }
     else
     {
         elems = new OtpErlangObject[] { elem };
     }
 }
示例#2
0
 public OtpErlangFun(OtpErlangPid pid, String module,
     long index, long uniq, OtpErlangObject[] freeVars)
 {
     this.pid = pid;
     this.module = module;
     arity = -1;
     md5 = null;
     this.index = index;
     old_index = 0;
     this.uniq = uniq;
     this.freeVars = freeVars;
 }
示例#3
0
 public OtpErlangFun(OtpErlangPid pid, String module,
     int arity, byte[] md5, int index,
     long old_index, long uniq,
     OtpErlangObject[] freeVars)
 {
     this.pid = pid;
     this.module = module;
     this.arity = arity;
     this.md5 = md5;
     this.index = index;
     this.old_index = old_index;
     this.uniq = uniq;
     this.freeVars = freeVars;
 }
        /*
         * Send an auth error to peer because he sent a bad cookie. The auth error
         * uses his cookie (not revealing ours). This is just like send_reg
         * otherwise
         */
        private void cookieError(OtpLocalNode local, OtpErlangAtom cookie)
        {
            try
            {
                OtpOutputStream header = new OtpOutputStream(headerLen);

                // preamble: 4 byte length + "passthrough" tag + version
                header.write4BE(0); // reserve space for length
                header.write1(passThrough);
                header.write1(version);

                header.write_tuple_head(4);
                header.write_long(regSendTag);
                header.write_any(local.createPid()); // disposable pid
                header.write_atom(cookie.atomValue()); // important: his cookie,
                // not mine...
                header.write_atom("auth");

                // version for payload
                header.write1(version);

                // the payload

                // the no_auth message (copied from Erlang) Don't change this
                // (Erlang will crash)
                // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
                // [foo@aule]}}
                OtpErlangObject[] msg = new OtpErlangObject[2];
                OtpErlangObject[] msgbody = new OtpErlangObject[3];

                msgbody[0] = new OtpErlangAtom("print");
                msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local + " **~n");

                // Erlang will crash and burn if there is no third argument here...
                msgbody[2] = new OtpErlangList(); // empty list

                msg[0] = new OtpErlangAtom("$gen_cast");
                msg[1] = new OtpErlangTuple(msgbody);

                OtpOutputStream payload = new OtpOutputStream(new OtpErlangTuple(msg));

                // fix up length in preamble
                header.poke4BE(0, header.size() + payload.size() - 4);

                try
                {
                    do_send(header, payload);
                }
                catch (IOException)
                {
                } // ignore
            }
            finally
            {
                close();
            }
            throw new OtpAuthException("Remote cookie not authorized: " + cookie.atomValue());
        }
 /**
  * Send an exit signal to a remote process.
  *
  * @param dest
  *            the Erlang PID of the remote process.
  * @param reason
  *            an Erlang term describing the exit reason.
  *
  * @exception java.io.IOException
  *                if the connection is not active or a communication error
  *                occurs.
  */
 protected void sendExit2(OtpErlangPid from, OtpErlangPid dest, OtpErlangObject reason)
 {
     sendExit(exit2Tag, from, dest, reason);
 }
示例#6
0
 /**
  * <p>
  * Send an exit signal to a remote {@link OtpErlangPid pid}. This method
  * does not cause any links to be broken, except indirectly if the remote
  * {@link OtpErlangPid pid} exits as a result of this exit signal.
  * </p>
  *
  * @param to
  *                the {@link OtpErlangPid pid} to which the exit signal
  *                should be sent.
  *
  * @param reason
  *                an Erlang term indicating the reason for the exit.
  */
 // it's called exit, but it sends exit2
 public void exit(OtpErlangPid to, OtpErlangObject reason)
 {
     exit(2, to, reason);
 }
示例#7
0
        /* create the outgoing ping message */
        private OtpErlangTuple getPingTuple(OtpMbox mbox)
        {
            OtpErlangObject[] ping = new OtpErlangObject[3];
            OtpErlangObject[] pid = new OtpErlangObject[2];
            OtpErlangObject[] node = new OtpErlangObject[2];

            pid[0] = mbox.Self;
            pid[1] = createRef();

            node[0] = new OtpErlangAtom("is_auth");
            node[1] = new OtpErlangAtom(Node);

            ping[0] = new OtpErlangAtom("$gen_call");
            ping[1] = new OtpErlangTuple(pid);
            ping[2] = new OtpErlangTuple(node);

            return new OtpErlangTuple(ping);
        }
示例#8
0
 /**
  * Send a message to a named mailbox created from the same node as this
  * mailbox.
  *
  * @param name
  *                the registered name of recipient mailbox.
  *
  * @param msg
  *                the body of the message to send.
  *
  */
 public void send(String name, OtpErlangObject msg)
 {
     home.deliver(new OtpMsg(self, name, (OtpErlangObject)msg.Clone()));
 }
 /**
  * Get all the elements from the tuple as an array.
  *
  * @return an array containing all of the tuple's elements.
  */
 public OtpErlangObject[] elements()
 {
     OtpErlangObject[] res = new OtpErlangObject[arity()];
     Array.Copy(elems, 0, res, 0, res.Length);
     return res;
 }
示例#10
0
 public OtpErlangFun read_fun()
 {
     int tag = read1skip_version();
     if (tag == OtpExternal.funTag)
     {
         int nFreeVars = read4BE();
         OtpErlangPid pid = read_pid();
         String module = read_atom();
         long index = read_long();
         long uniq = read_long();
         OtpErlangObject[] freeVars = new OtpErlangObject[nFreeVars];
         for (int i = 0; i < nFreeVars; ++i)
         {
             freeVars[i] = read_any();
         }
         return new OtpErlangFun(pid, module, index, uniq, freeVars);
     }
     else if (tag == OtpExternal.newFunTag)
     {
         read4BE();
         int arity = read1();
         byte[] md5 = new byte[16];
         readN(md5);
         int index = read4BE();
         int nFreeVars = read4BE();
         String module = read_atom();
         long oldIndex = read_long();
         long uniq = read_long();
         OtpErlangPid pid = read_pid();
         OtpErlangObject[] freeVars = new OtpErlangObject[nFreeVars];
         for (int i = 0; i < nFreeVars; ++i)
         {
             freeVars[i] = read_any();
         }
         return new OtpErlangFun(pid, module, arity, md5, index, oldIndex, uniq, freeVars);
     }
     else
     {
         throw new OtpErlangDecodeException("Wrong tag encountered, expected fun, got " + tag);
     }
 }
 /*
  * this one called explicitely by user code => use exit2
  */
 public void exit2(OtpErlangPid from, OtpErlangPid to, OtpErlangObject reason)
 {
     try
     {
         base.sendExit2(from, to, reason);
     }
     catch (Exception)
     {
     }
 }
示例#12
0
 /**
  * Create a stream containing the encoded version of the given Erlang term.
  */
 public OtpOutputStream(OtpErlangObject o)
     : base()
 {
     write_any(o);
 }
示例#13
0
 public void write_fun(OtpErlangPid pid, String module,
     long old_index, int arity, byte[] md5,
     long index, long uniq, OtpErlangObject[] freeVars)
 {
     if (arity == -1)
     {
         write1(OtpExternal.funTag);
         write4BE(freeVars.Length);
         pid.encode(this);
         write_atom(module);
         write_long(index);
         write_long(uniq);
         foreach (OtpErlangObject fv in freeVars)
         {
             fv.encode(this);
         }
     }
     else
     {
         write1(OtpExternal.newFunTag);
         int saveSizePos = getPos();
         write4BE(0); // this is where we patch in the size
         write1(arity);
         writeN(md5);
         write4BE(index);
         write4BE(freeVars.Length);
         write_atom(module);
         write_long(old_index);
         write_long(uniq);
         pid.encode(this);
         foreach (OtpErlangObject fv in freeVars)
         {
             fv.encode(this);
         }
         poke4BE(saveSizePos, getPos() - saveSizePos);
     }
 }
示例#14
0
 /**
  * Write an arbitrary Erlang term to the stream in compressed format.
  *
  * @param o
  *            the Erlang tem to write.
  */
 public void write_compressed(OtpErlangObject o)
 {
     OtpOutputStream oos = new OtpOutputStream(o);
     write1(OtpExternal.compressedTag);
     write4BE(oos.Length);
     DeflateStream dos = new DeflateStream(this, CompressionMode.Compress, true);
     try
     {
         oos.WriteTo(dos);
         dos.Close();
     }
     catch (ObjectDisposedException)
     {
         throw new ArgumentException("Intremediate stream failed for Erlang object " + o);
     }
 }
示例#15
0
 /**
  * Write an arbitrary Erlang term to the stream.
  *
  * @param o
  *            the Erlang term to write.
  */
 public void write_any(OtpErlangObject o)
 {
     // calls one of the above functions, depending on o
     o.encode(this);
 }
示例#16
0
        // this function used internally when "process" dies
        // since Erlang discerns between exit and exit/2.
        private void exit(int arity, OtpErlangPid to, OtpErlangObject reason)
        {
            try
            {
                String node = to.Node;
                if (node.Equals(home.Node))
                {
                    home.deliver(new OtpMsg(OtpMsg.exitTag, self, to, reason));
                }
                else
                {
                    OtpCookedConnection conn = home.getConnection(node);
                    if (conn == null)
                    {
                        return;
                    }
                    switch (arity)
                    {
                        case 1:
                            conn.exit(self, to, reason);
                            break;

                        case 2:
                            conn.exit2(self, to, reason);
                            break;
                    }
                }
            }
            catch (Exception)
            {
            }
        }
示例#17
0
 /**
  * Send a message to a named mailbox created from another node.
  *
  * @param name
  *                the registered name of recipient mailbox.
  *
  * @param node
  *                the name of the remote node where the recipient mailbox is
  *                registered.
  *
  * @param msg
  *                the body of the message to send.
  *
  */
 public void send(String name, String node, OtpErlangObject msg)
 {
     try
     {
         String currentNode = home.Node;
         if (node.Equals(currentNode))
         {
             send(name, msg);
         }
         else if (node.IndexOf('@', 0) < 0 && node.Equals(currentNode.Substring(0, currentNode.IndexOf('@', 0))))
         {
             send(name, msg);
         }
         else
         {
             // other node
             OtpCookedConnection conn = home.getConnection(node);
             if (conn == null)
             {
                 return;
             }
             conn.send(self, name, msg);
         }
     }
     catch (Exception)
     {
     }
 }
        private void sendExit(int tag, OtpErlangPid from, OtpErlangPid dest, OtpErlangObject reason)
        {
            if (!connected)
            {
                throw new IOException("Not connected");
            }
            OtpOutputStream header = new OtpOutputStream(headerLen);

            // preamble: 4 byte length + "passthrough" tag
            header.write4BE(0); // reserve space for length
            header.write1(passThrough);
            header.write1(version);

            // header
            header.write_tuple_head(4);
            header.write_long(tag);
            header.write_any(from);
            header.write_any(dest);
            header.write_any(reason);

            // fix up length in preamble
            header.poke4BE(0, header.size() - 4);

            do_send(header);
        }
        protected String headerType(OtpErlangObject h)
        {
            int tag = -1;

            if (h is OtpErlangTuple)
            {
                tag = (int)((OtpErlangLong)((OtpErlangTuple)h).elementAt(0)).longValue();
            }

            switch (tag)
            {
                case linkTag:
                    return "LINK";

                case sendTag:
                    return "SEND";

                case exitTag:
                    return "EXIT";

                case unlinkTag:
                    return "UNLINK";

                case nodeLinkTag:
                    return "NODELINK";

                case regSendTag:
                    return "REG_SEND";

                case groupLeaderTag:
                    return "GROUP_LEADER";

                case exit2Tag:
                    return "EXIT2";

                case sendTTTag:
                    return "SEND_TT";

                case exitTTTag:
                    return "EXIT_TT";

                case regSendTTTag:
                    return "REG_SEND_TT";

                case exit2TTTag:
                    return "EXIT2_TT";
            }

            return "(unknown type)";
        }
 /*
  * send to remote name dest is recipient's registered name, the nodename is
  * implied by the choice of connection.
  */
 public void send(OtpErlangPid from, String dest, OtpErlangObject msg)
 {
     // encode and send the message
     sendBuf(from, dest, new OtpOutputStream(msg));
 }
示例#21
0
 /**
  * Create a tuple from an array of terms.
  *
  * @param elems
  *                the array of terms to create the tuple from.
  * @param start
  *                the offset of the first term to insert.
  * @param count
  *                the number of terms to insert.
  *
  * @exception java.lang.IllegalArgumentException
  *                    if the array is empty (null) or contains null
  *                    elements.
  */
 public OtpErlangTuple(OtpErlangObject[] elems, int start, int count)
 {
     if (elems == null)
     {
         throw new ArgumentException("Tuple content can't be null");
     }
     else if (count < 1)
     {
         elems = NO_ELEMENTS;
     }
     else
     {
         this.elems = new OtpErlangObject[count];
         for (int i = 0; i < count; i++)
         {
             if (elems[start + i] != null)
             {
                 this.elems[i] = elems[start + i];
             }
             else
             {
                 throw new ArgumentException("Tuple element cannot be null (element" + (start + i) + ")");
             }
         }
     }
 }
示例#22
0
 /**
  * Create a tuple from an array of terms.
  *
  * @param elems
  *                the array of terms to create the tuple from.
  *
  * @exception java.lang.IllegalArgumentException
  *                    if the array is empty (null) or contains null
  *                    elements.
  */
 public OtpErlangTuple(OtpErlangObject[] elems)
     : this(elems, 0, elems.Length)
 {
 }
示例#23
0
 /**
  * Send an exit signal to a remote process.
  *
  * @param dest
  *                the Erlang PID of the remote process.
  * @param reason
  *                an Erlang term describing the exit reason.
  *
  * @exception java.io.IOException
  *                    if the connection is not active or a communication
  *                    error occurs.
  */
 public void exit(OtpErlangPid dest, OtpErlangObject reason)
 {
     base.sendExit2(self.Pid, dest, reason);
 }
示例#24
0
 /**
  * Send a message to a remote {@link OtpErlangPid pid}, representing either
  * another {@link OtpMbox mailbox} or an Erlang process.
  *
  * @param to
  *                the {@link OtpErlangPid pid} identifying the intended
  *                recipient of the message.
  *
  * @param msg
  *                the body of the message to send.
  *
  */
 public void send(OtpErlangPid to, OtpErlangObject msg)
 {
     try
     {
         String node = to.Node;
         if (node.Equals(home.Node))
         {
             home.deliver(new OtpMsg(to, (OtpErlangObject)msg.Clone()));
         }
         else
         {
             OtpCookedConnection conn = home.getConnection(node);
             if (conn == null)
             {
                 return;
             }
             conn.send(self, to, msg);
         }
     }
     catch (Exception)
     {
     }
 }
示例#25
0
 /**
  * Send a message to a named process on a remote node.
  *
  * @param dest
  *                the name of the remote process.
  * @param msg
  *                the message to send.
  *
  * @exception java.io.IOException
  *                    if the connection is not active or a communication
  *                    error occurs.
  */
 public void send(String dest, OtpErlangObject msg)
 {
     // encode and send the message
     base.sendBuf(self.Pid, dest, new OtpOutputStream(msg));
 }
示例#26
0
 /**
  * Send an RPC request to the remote Erlang node. This convenience function
  * creates the following message and sends it to 'rex' on the remote node:
  *
  * <pre>
  * { self, { call, Mod, Fun, Args, user } }
  * </pre>
  *
  * <p>
  * Note that this method has unpredicatble results if the remote node is not
  * an Erlang node.
  * </p>
  *
  * @param mod
  *                the name of the Erlang module containing the function to
  *                be called.
  * @param fun
  *                the name of the function to call.
  * @param args
  *                an array of Erlang terms, to be used as arguments to the
  *                function.
  *
  * @exception java.io.IOException
  *                    if the connection is not active or a communication
  *                    error occurs.
  */
 public void sendRPC(String mod, String fun, OtpErlangObject[] args)
 {
     sendRPC(mod, fun, new OtpErlangList(args));
 }
示例#27
0
 /**
  * Close the specified mailbox with the given reason.
  *
  * @param mbox
  *            the mailbox to close.
  * @param reason
  *            an Erlang term describing the reason for the termination.
  *
  *            <p>
  *            After this operation, the mailbox will no longer be able to
  *            receive messages. Any delivered but as yet unretrieved
  *            messages can still be retrieved however.
  *            </p>
  *
  *            <p>
  *            If there are links from the mailbox to other
  *            {@link OtpErlangPid pids}, they will be broken when this
  *            method is called and exit signals with the given reason will
  *            be sent.
  *            </p>
  *
  */
 public void closeMbox(OtpMbox mbox, OtpErlangObject reason)
 {
     if (mbox != null)
     {
         mboxes.remove(mbox);
         mbox.Name = null;
         mbox.breakLinks(reason);
     }
 }
示例#28
0
        /**
         * Send an RPC request to the remote Erlang node. This convenience function
         * creates the following message and sends it to 'rex' on the remote node:
         *
         * <pre>
         * { self, { call, Mod, Fun, Args, user } }
         * </pre>
         *
         * <p>
         * Note that this method has unpredicatble results if the remote node is not
         * an Erlang node.
         * </p>
         *
         * @param mod
         *                the name of the Erlang module containing the function to
         *                be called.
         * @param fun
         *                the name of the function to call.
         * @param args
         *                a list of Erlang terms, to be used as arguments to the
         *                function.
         *
         * @exception java.io.IOException
         *                    if the connection is not active or a communication
         *                    error occurs.
         */
        public void sendRPC(String mod, String fun, OtpErlangList args)
        {
            OtpErlangObject[] rpc = new OtpErlangObject[2];
            OtpErlangObject[] call = new OtpErlangObject[5];

            /* {self, { call, Mod, Fun, Args, user}} */

            call[0] = new OtpErlangAtom("call");
            call[1] = new OtpErlangAtom(mod);
            call[2] = new OtpErlangAtom(fun);
            call[3] = args;
            call[4] = new OtpErlangAtom("user");

            rpc[0] = self.Pid;
            rpc[1] = new OtpErlangTuple(call);

            send("rex", new OtpErlangTuple(rpc));
        }
示例#29
0
        /*
         * this method simulates net_kernel only for the purpose of replying to
         * pings.
         */
        private bool netKernel(OtpMsg m)
        {
            OtpMbox mbox = null;
            try
            {
                OtpErlangTuple t = (OtpErlangTuple)m.getMsg();
                OtpErlangTuple req = (OtpErlangTuple)t.elementAt(1); // actual
                // request

                OtpErlangPid pid = (OtpErlangPid)req.elementAt(0); // originating
                // pid

                OtpErlangObject[] pong = new OtpErlangObject[2];
                pong[0] = req.elementAt(1); // his #Ref
                pong[1] = new OtpErlangAtom("yes");

                mbox = createMbox(true);
                mbox.send(pid, new OtpErlangTuple(pong));
                return true;
            }
            catch (Exception)
            {
            }
            finally
            {
                closeMbox(mbox);
            }
            return false;
        }
示例#30
0
 /**
  * Close this mailbox with the given reason.
  *
  * <p>
  * After this operation, the mailbox will no longer be able to receive
  * messages. Any delivered but as yet unretrieved messages can still be
  * retrieved however.
  * </p>
  *
  * <p>
  * If there are links from this mailbox to other {@link OtpErlangPid pids},
  * they will be broken when this method is called and exit signals will be
  * sent.
  * </p>
  *
  * @param reason
  *                an Erlang term describing the reason for the exit.
  */
 public void exit(OtpErlangObject reason)
 {
     home.closeMbox(this, reason);
 }