Ejemplo n.º 1
0
        //    This is called by underlying base class code, each time a new response is received from the wire or a protocol stage is resumed.
        //    This function controls the setting up of a data socket/connection, and of saving off the server responses.
        protected override PipelineInstruction PipelineCallback(PipelineEntry entry, ResponseDescription response, bool timeout, ref Stream stream)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"Command:{entry?.Command} Description:{response?.StatusDescription}");
            }

            // null response is not expected
            if (response == null)
            {
                return(PipelineInstruction.Abort);
            }

            FtpStatusCode status = (FtpStatusCode)response.Status;

            //
            // Update global "current status" for FtpWebRequest
            //
            if (status != FtpStatusCode.ClosingControl)
            {
                // A 221 status won't be reflected on the user FTP response
                // Anything else will (by design?)
                StatusCode = status;
                StatusLine = response.StatusDescription;
            }

            // If the status code is outside the range defined in RFC (1xx to 5xx) throw
            if (response.InvalidStatusCode)
            {
                throw new WebException(SR.net_InvalidStatusCode, WebExceptionStatus.ProtocolError);
            }

            // Update the banner message if any, this is a little hack because the "entry" param is null
            if (_index == -1)
            {
                if (status == FtpStatusCode.SendUserCommand)
                {
                    _bannerMessage = new StringBuilder();
                    _bannerMessage.Append(StatusLine);
                    return(PipelineInstruction.Advance);
                }
                else if (status == FtpStatusCode.ServiceTemporarilyNotAvailable)
                {
                    return(PipelineInstruction.Reread);
                }
                else
                {
                    throw GenerateException(status, response.StatusDescription, null);
                }
            }

            //
            // Check for the result of our attempt to use UTF8
            //
            if (entry.Command == "OPTS utf8 on\r\n")
            {
                if (response.PositiveCompletion)
                {
                    Encoding = Encoding.UTF8;
                }
                else
                {
                    Encoding = Encoding.Default;
                }
                return(PipelineInstruction.Advance);
            }

            // If we are already logged in and the server returns 530 then
            // the server does not support re-issuing a USER command,
            // tear down the connection and start all over again
            if (entry.Command.IndexOf("USER") != -1)
            {
                // The server may not require a password for this user, so bypass the password command
                if (status == FtpStatusCode.LoggedInProceed)
                {
                    _loginState = FtpLoginState.LoggedIn;
                    _index++;
                }
            }

            //
            // Throw on an error with possible recovery option
            //
            if (response.TransientFailure || response.PermanentFailure)
            {
                if (status == FtpStatusCode.ServiceNotAvailable)
                {
                    MarkAsRecoverableFailure();
                }
                throw GenerateException(status, response.StatusDescription, null);
            }

            if (_loginState != FtpLoginState.LoggedIn &&
                entry.Command.IndexOf("PASS") != -1)
            {
                // Note the fact that we logged in
                if (status == FtpStatusCode.NeedLoginAccount || status == FtpStatusCode.LoggedInProceed)
                {
                    _loginState = FtpLoginState.LoggedIn;
                }
                else
                {
                    throw GenerateException(status, response.StatusDescription, null);
                }
            }

            //
            // Parse special cases
            //
            if (entry.HasFlag(PipelineEntryFlags.CreateDataConnection) && (response.PositiveCompletion || response.PositiveIntermediate))
            {
                bool isSocketReady;
                PipelineInstruction result = QueueOrCreateDataConection(entry, response, timeout, ref stream, out isSocketReady);
                if (!isSocketReady)
                {
                    return(result);
                }
                // otherwise we have a stream to create
            }
            //
            // This is part of the above case and it's all about giving data stream back
            //
            if (status == FtpStatusCode.OpeningData || status == FtpStatusCode.DataAlreadyOpen)
            {
                if (_dataSocket == null)
                {
                    return(PipelineInstruction.Abort);
                }
                if (!entry.HasFlag(PipelineEntryFlags.GiveDataStream))
                {
                    _abortReason = SR.Format(SR.net_ftp_invalid_status_response, status, entry.Command);
                    return(PipelineInstruction.Abort);
                }

                // Parse out the Content length, if we can
                TryUpdateContentLength(response.StatusDescription);

                // Parse out the file name, when it is returned and use it for our ResponseUri
                FtpWebRequest request = (FtpWebRequest)_request;
                if (request.MethodInfo.ShouldParseForResponseUri)
                {
                    TryUpdateResponseUri(response.StatusDescription, request);
                }

                return(QueueOrCreateFtpDataStream(ref stream));
            }


            //
            // Parse responses by status code exclusivelly
            //

            // Update welcome message
            if (status == FtpStatusCode.LoggedInProceed)
            {
                _welcomeMessage.Append(StatusLine);
            }
            // OR set the user response ExitMessage
            else if (status == FtpStatusCode.ClosingControl)
            {
                _exitMessage.Append(response.StatusDescription);
                // And close the control stream socket on "QUIT"
                CloseSocket();
            }
            // OR set us up for SSL/TLS, after this we'll be writing securely
            else if (status == FtpStatusCode.ServerWantsSecureSession)
            {
                // If NetworkStream is a TlsStream, then this must be in the async callback
                // from completing the SSL handshake.
                // So just let the pipeline continue.
                if (!(NetworkStream is TlsStream))
                {
                    FtpWebRequest request   = (FtpWebRequest)_request;
                    TlsStream     tlsStream = new TlsStream(NetworkStream, Socket, request.RequestUri.Host, request.ClientCertificates);

                    if (_isAsync)
                    {
                        tlsStream.BeginAuthenticateAsClient(ar =>
                        {
                            try
                            {
                                tlsStream.EndAuthenticateAsClient(ar);
                                NetworkStream = tlsStream;
                                this.ContinueCommandPipeline();
                            }
                            catch (Exception e)
                            {
                                this.CloseSocket();
                                this.InvokeRequestCallback(e);
                            }
                        }, null);

                        return(PipelineInstruction.Pause);
                    }
                    else
                    {
                        tlsStream.AuthenticateAsClient();
                        NetworkStream = tlsStream;
                    }
                }
            }
            // OR parse out the file size or file time, usually a result of sending SIZE/MDTM commands
            else if (status == FtpStatusCode.FileStatus)
            {
                FtpWebRequest request = (FtpWebRequest)_request;
                if (entry.Command.StartsWith("SIZE "))
                {
                    _contentLength = GetContentLengthFrom213Response(response.StatusDescription);
                }
                else if (entry.Command.StartsWith("MDTM "))
                {
                    _lastModified = GetLastModifiedFrom213Response(response.StatusDescription);
                }
            }
            // OR parse out our login directory
            else if (status == FtpStatusCode.PathnameCreated)
            {
                if (entry.Command == "PWD\r\n" && !entry.HasFlag(PipelineEntryFlags.UserCommand))
                {
                    _loginDirectory = GetLoginDirectory(response.StatusDescription);
                }
            }
            // Asserting we have some positive response
            else
            {
                // We only use CWD to reset ourselves back to the login directory.
                if (entry.Command.IndexOf("CWD") != -1)
                {
                    _establishedServerDirectory = _requestedServerDirectory;
                }
            }

            // Intermediate responses require rereading
            if (response.PositiveIntermediate || (!UsingSecureStream && entry.Command == "AUTH TLS\r\n"))
            {
                return(PipelineInstruction.Reread);
            }

            return(PipelineInstruction.Advance);
        }
Ejemplo n.º 2
0
        //Updates Pipeline Map
        public void setPipelineTexts(Label pNum, Label pFetch, Label pDecode, Label pExecute, Label pStore, PipelineInstruction instr)
        {
            String nullLine = "--------------";

            pNum.Text = instr.instructionText + "(" + instr.instructionIndex + ")";
            switch (instr.stage)
            {
            case 4:
                pFetch.Text        = "F";
                pFetch.ForeColor   = Color.DarkGreen;
                pDecode.Text       = "D";
                pDecode.ForeColor  = Color.DarkGreen;
                pExecute.Text      = "X";
                pExecute.ForeColor = Color.DarkGreen;
                pStore.Text        = "M";
                pStore.ForeColor   = Color.DarkGreen;
                pNum.ForeColor     = Color.DarkGreen;
                break;

            case 3:
                pFetch.Text        = "F";
                pDecode.Text       = "D";
                pExecute.Text      = "X";
                pStore.Text        = nullLine;
                pFetch.ForeColor   = label47.ForeColor;
                pDecode.ForeColor  = label47.ForeColor;
                pExecute.ForeColor = label47.ForeColor;
                pStore.ForeColor   = label47.ForeColor;
                pNum.ForeColor     = label47.ForeColor;

                break;

            case 2:
                pFetch.Text        = "F";
                pDecode.Text       = "D";
                pExecute.Text      = nullLine;
                pStore.Text        = nullLine;
                pFetch.ForeColor   = label47.ForeColor;
                pDecode.ForeColor  = label47.ForeColor;
                pExecute.ForeColor = label47.ForeColor;
                pStore.ForeColor   = label47.ForeColor;
                pNum.ForeColor     = label47.ForeColor;

                break;

            case 1:
                pFetch.Text   = "F";
                pDecode.Text  = nullLine;
                pExecute.Text = nullLine;
                pStore.Text   = nullLine;
                break;
                pFetch.ForeColor   = label47.ForeColor;
                pDecode.ForeColor  = label47.ForeColor;
                pExecute.ForeColor = label47.ForeColor;
                pStore.ForeColor   = label47.ForeColor;
                pNum.ForeColor     = label47.ForeColor;

            case 0:
                pFetch.Text        = nullLine;
                pDecode.Text       = nullLine;
                pExecute.Text      = nullLine;
                pStore.Text        = nullLine;
                pFetch.ForeColor   = label47.ForeColor;
                pDecode.ForeColor  = label47.ForeColor;
                pExecute.ForeColor = label47.ForeColor;
                pStore.ForeColor   = label47.ForeColor;
                pNum.ForeColor     = label47.ForeColor;

                break;
            }
        }
Ejemplo n.º 3
0
        //Updates Pipeline Map
       public void setPipelineTexts(Label pNum, Label pFetch, Label pDecode, Label pExecute, Label pStore, PipelineInstruction instr)
       {
           String nullLine = "--------------";
           pNum.Text = instr.instructionText + "(" + instr.instructionIndex + ")";
           switch (instr.stage)
           {
               case 4:
                   pFetch.Text = "F";
                   pFetch.ForeColor = Color.DarkGreen;
                   pDecode.Text = "D";
                   pDecode.ForeColor = Color.DarkGreen;
                   pExecute.Text = "X";
                   pExecute.ForeColor = Color.DarkGreen;
                   pStore.Text = "M";
                   pStore.ForeColor = Color.DarkGreen;
                   pNum.ForeColor = Color.DarkGreen;
                   break;
               case 3:
                   pFetch.Text = "F";
                   pDecode.Text = "D";
                   pExecute.Text = "X";
                   pStore.Text = nullLine;
                   pFetch.ForeColor = label47.ForeColor;
                   pDecode.ForeColor = label47.ForeColor;
                   pExecute.ForeColor = label47.ForeColor;
                   pStore.ForeColor = label47.ForeColor;
                   pNum.ForeColor = label47.ForeColor;

                   break;
               case 2:
                   pFetch.Text = "F";
                   pDecode.Text = "D";
                   pExecute.Text = nullLine;
                   pStore.Text = nullLine;
                   pFetch.ForeColor = label47.ForeColor;
                   pDecode.ForeColor = label47.ForeColor;
                   pExecute.ForeColor = label47.ForeColor;
                   pStore.ForeColor = label47.ForeColor;
                   pNum.ForeColor = label47.ForeColor;

                   break;
               case 1:
                   pFetch.Text = "F";
                   pDecode.Text = nullLine;
                   pExecute.Text = nullLine;
                   pStore.Text = nullLine;
                   break;
                   pFetch.ForeColor = label47.ForeColor;
                   pDecode.ForeColor = label47.ForeColor;
                   pExecute.ForeColor = label47.ForeColor;
                   pStore.ForeColor = label47.ForeColor;
                   pNum.ForeColor = label47.ForeColor;

               case 0:
                   pFetch.Text = nullLine;
                   pDecode.Text = nullLine;
                   pExecute.Text = nullLine;
                   pStore.Text = nullLine;
                   pFetch.ForeColor = label47.ForeColor;
                   pDecode.ForeColor = label47.ForeColor;
                   pExecute.ForeColor = label47.ForeColor;
                   pStore.ForeColor = label47.ForeColor;
                   pNum.ForeColor = label47.ForeColor;

                   break;
           }
       }
Ejemplo n.º 4
0
        void myCPU_OnBranch(object sender, BranchEventArgs args)
        {
            MethodInvoker method = delegate
            {
                if (args.taken)
                {
                    Console.WriteLine("Branch taken in GUI " + this.myCPU.ACC);

                    /*What this code does is goes through the instructions in the pipeline,
                     * and removes the ones that were being worked on prior to the branch being
                     * taken
                     * NOTE: probably will have to add an if statement to check for branch prediction*/

                    int count = 0;
                    Console.WriteLine("Queue contents before:");
                    foreach (var instr in instructionsInPipeline)
                    {
                        Console.WriteLine(count + ") " + instr.instructionText + ", stage is " + instr.stage);
                        count++;
                    }

                    PipelineInstruction[] temp = new PipelineInstruction[instructionsInPipeline.Count()];
                    instructionsInPipeline.CopyTo(temp, 0);
                    instructionsInPipeline.Clear();
                    int takenBranchIndex = args.CurrentInstrIndex;
                    Console.WriteLine("Taken branch index is " + takenBranchIndex);
                    for (int i = 0; i < temp.Count(); i++)
                    {
                        //if the index is larger than the branch that was taken, it needs to be flushed out
                        if ((temp[i]).instructionIndex < takenBranchIndex)
                        {
                            instructionsInPipeline.Enqueue(temp[i]);
                        }
                        else if (temp[i].instructionIndex == takenBranchIndex)
                        {
                            temp[i].stage++;//this is to correct for the special branch case
                            instructionsInPipeline.Enqueue(temp[i]);
                        }
                    }

                    count = 0;
                    Console.WriteLine("Queue contents after:");
                    foreach (var instr in instructionsInPipeline)
                    {
                        Console.WriteLine(count + ") " + instr.instructionText + ", stage is " + instr.stage);
                        count++;
                    }
                    //this.setPipelineValuesToView();
                }

                foreach (var branch in bhtBranches)
                {
                    String currBranchName = Memory.getAssemblyInstructions().ElementAt(args.CurrentInstrIndex);
                    if (currBranchName.CompareTo(branch.instrLabel) == 0)
                    {
                        if (args.taken)
                        {
                            branch.takenCount++;
                        }
                        else
                        {
                            branch.notTakenCount++;
                        }
                    }
                }
                //updateGUI();
            };

            if (this.InvokeRequired)
            {
                this.Invoke(method);
            }
            else
            {
                method.Invoke();
            }
        }
Ejemplo n.º 5
0
        void myCPU_OnBranch(object sender, BranchEventArgs args)
        {
            MethodInvoker method = delegate
            {
                if (args.taken)
                {


                    Console.WriteLine("Branch taken in GUI " + this.myCPU.ACC);

                    /*What this code does is goes through the instructions in the pipeline,
                      and removes the ones that were being worked on prior to the branch being
                      taken
                     NOTE: probably will have to add an if statement to check for branch prediction*/

                    int count = 0;
                    Console.WriteLine("Queue contents before:");
                    foreach (var instr in instructionsInPipeline)
                    {
                        Console.WriteLine(count + ") " + instr.instructionText + ", stage is " + instr.stage);
                        count++;
                    }

                    PipelineInstruction[] temp = new PipelineInstruction[instructionsInPipeline.Count()];
                    instructionsInPipeline.CopyTo(temp, 0);
                    instructionsInPipeline.Clear();
                    int takenBranchIndex = args.CurrentInstrIndex;
                    Console.WriteLine("Taken branch index is " + takenBranchIndex);
                    for (int i = 0; i < temp.Count(); i++)
                    {
                        //if the index is larger than the branch that was taken, it needs to be flushed out
                        if ((temp[i]).instructionIndex < takenBranchIndex)
                        {
                            instructionsInPipeline.Enqueue(temp[i]);
                        }
                        else if (temp[i].instructionIndex == takenBranchIndex)
                        {
                            temp[i].stage++;//this is to correct for the special branch case
                            instructionsInPipeline.Enqueue(temp[i]);
                        }
                    }

                    count = 0;
                    Console.WriteLine("Queue contents after:");
                    foreach (var instr in instructionsInPipeline)
                    {
                        Console.WriteLine(count + ") " + instr.instructionText + ", stage is " + instr.stage);
                        count++;
                    }
                    //this.setPipelineValuesToView();

                }          

                foreach(var branch in bhtBranches){
                    String currBranchName = Memory.getAssemblyInstructions().ElementAt(args.CurrentInstrIndex);
                    if (currBranchName.CompareTo(branch.instrLabel) == 0)
                    {
                        if (args.taken)
                        {
                            branch.takenCount++;
                        }
                        else
                        {
                            branch.notTakenCount++;
                        }
                    }
                }
                //updateGUI();
            };

            if (this.InvokeRequired)
            {
                this.Invoke(method);
            }
            else
            {
                method.Invoke();
            }
        }