示例#1
0
 /// <summary>Extracts the nodes.</summary>
 /// <param name="nodes">The nodes.</param>
 /// <param name="nodesList">The nodes list.</param>
 private void ExtractNodes(IList <Node> nodes, OtpErlangList nodesList)
 {
     foreach (var erlangNodeName in nodesList)
     {
         var nodeName = erlangNodeName.ToString();
         nodes.Add(new Node(nodeName));
     }
 }
示例#2
0
 /// <summary>Extracts the applications.</summary>
 /// <param name="applications">The applications.</param>
 /// <param name="appList">The app list.</param>
 private void ExtractApplications(IList <Application> applications, OtpErlangList appList)
 {
     foreach (var appDescription in appList)
     {
         var appDescriptionTuple = (OtpErlangTuple)appDescription;
         var name        = appDescriptionTuple.elementAt(0).ToString();
         var description = appDescriptionTuple.elementAt(1).ToString();
         var version     = appDescriptionTuple.elementAt(2).ToString();
         applications.Add(new Application(name, description, version));
     }
 }
 /// <summary>Executes the erlang RPC.</summary>
 /// <param name="module">The module.</param>
 /// <param name="function">The function.</param>
 /// <param name="args">The args.</param>
 /// <returns>The OtpErlangObject.</returns>
 public OtpErlangObject ExecuteErlangRpc(string module, string function, OtpErlangList args)
 {
     return(this.Execute(
                delegate(IConnection connection)
     {
         Logger.Debug("Sending RPC for module [" + module + "] function [" + function + "] args [" + args);
         connection.SendRPC(module, function, args);
         var response = connection.ReceiveRPC();
         Logger.Debug("Response received = " + response);
         this.HandleResponseError(module, function, response);
         return response;
     }));
 }
        /**
         * Create an Erlang string from a list of integers.
         *
         * @return an Erlang string with Unicode code units.
         *
         * @throws OtpErlangException
         *                for non-proper and non-integer lists.
         * @throws OtpErlangRangeException
         *                if an integer in the list is not
         *                a valid Unicode code point according to Erlang.
         */
        public OtpErlangString(OtpErlangList list)
        {
            String s = list.stringValue();

            int[] offset = System.Globalization.StringInfo.ParseCombiningCharacters(s);
            int n = offset.Length;
            for (int i = 0; i < n; i++)
            {
                int cp = (int)codePointAt(s, offset[i]);
                if (!isValidCodePoint(cp))
                {
                    throw new OtpErlangRangeException("Invalid CodePoint: " + cp);
                }
            }
            str = s;
        }
        /*
         * 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());
        }
示例#6
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));
        }
示例#7
0
 /// <summary>Sends the RPC.</summary>
 /// <param name="mod">The mod.</param>
 /// <param name="fun">The fun.</param>
 /// <param name="args">The args.</param>
 public void SendRPC(string mod, string fun, OtpErlangList args)
 {
     this.otpConnection.sendRPC(mod, fun, args);
 }
示例#8
0
        /// <summary>
        /// Executes a MFA over TCP stream and synchronously retrieves the data
        /// </summary>
        /// <param name="stream">TCP stream</param>
        /// <param name="module">Erlang Module atom</param>
        /// <param name="function">Erlang function atom</param>
        /// <param name="args">Function arguments (maybe empty/null)</param>
        /// <returns></returns>
        public static OtpErlangObject CallMFASync(ErlStream stream,
            string module, string function, OtpErlangObject[] args)
        {
            OtpErlangObject[] mfaArray = null;
            OtpOutputStream eouts = new OtpOutputStream();

            mfaArray = new OtpErlangObject[4];

            // mod and fun and args as list
            // ['mod', 'fun', arg1, arg2, ...]
            mfaArray[0] = new OtpErlangAtom("c#ref");
            mfaArray[1] = new OtpErlangAtom(module);
            mfaArray[2] = new OtpErlangAtom(function);
            if (null != args)
                mfaArray[3] = new OtpErlangList(args);
            else
                mfaArray[3] = new OtpErlangList();

            OtpErlangTuple mfaTouple = new OtpErlangTuple(mfaArray);
            eouts = new OtpOutputStream();
            mfaTouple.encode(eouts);

            uint payloadLen = (uint)(eouts.Length + 1);
            byte[] buf = new byte[eouts.Length + 5];

            // added payload size (including protocol id byte)
            // and the missing protocol id byte after it
            buf[0] = (byte)((payloadLen & 0xFF000000) >> 24);
            buf[1] = (byte)((payloadLen & 0x00FF0000) >> 16);
            buf[2] = (byte)((payloadLen & 0x0000FF00) >> 8);
            buf[3] = (byte)((payloadLen & 0x000000FF));
            buf[4] = 131;

            Array.Copy(eouts.GetBuffer(), 0, buf, 5, eouts.Length); // rest of the buffer copied

            stream.Write(buf, 0, buf.Length);

            // wait for data
            DateTime startToWaitForData = DateTime.Now;
            while (!stream.DataAvailable)
            {
                if ((DateTime.Now - startToWaitForData).Seconds > Properties.Settings.Default.StreamResponseTimeout)
                    throw new ErlnetException("Response timeout in call to " + module + ":" + function);
                else
                    Thread.Sleep(0);
            }

            // read till empty
            int readCount = 0;
            payloadLen = 0;

            // read payload length (4 byte header)
            byte[] payloadbuf = new byte[4];
            do {
                readCount += stream.Read(payloadbuf, readCount, payloadbuf.Length - readCount);
                if (readCount != 4)
                    continue;
                else
                    payloadLen = ((uint)payloadbuf[3] & 0x000000FF)
                               + (((uint)payloadbuf[2] << 8) & 0x0000FF00)
                               + (((uint)payloadbuf[1] << 16) & 0x00FF0000)
                               + (((uint)payloadbuf[0] << 24) & 0xFF000000);
                break;
            } while(true);
            //Console.WriteLine("RX " + payloadLen + " bytes");

            // read the payload of length 'payloadLen'
            readCount = 0;
            buf = new byte[payloadLen];
            MemoryStream resp = new MemoryStream();
            do
            {
                readCount += stream.Read(buf, readCount, buf.Length - readCount);
                if (readCount != payloadLen)
                    continue;
                else
                    break;
            } while (true);

            // rebuild term
            resp.Write(buf, 0, buf.Length);
            OtpErlangTuple res = (OtpErlangTuple)OtpErlangObject.decode(new OtpInputStream(resp.GetBuffer()));

            //Console.WriteLine("RX " + res.elementAt(0).ToString());
            return res.elementAt(1);
        }