Example #1
0
        private bool LoadDirectory(string path)
        {
            Log.InfoFormat("Request directory listing for '{0}/{1}'", m_Session.SessionName, path);
            DirListingCallback dirCallback = delegate(RequestResult result, List <FileEntry> files)
            {
                switch (result)
                {
                case RequestResult.RetryAuthentication:
                    this.BeginInvoke(new Action(() =>
                    {
                        dlgLogin m_Login = new dlgLogin(m_Session);
                        if (m_Login.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                        {
                            m_Session.Username = m_Login.Username;
                            m_Session.Password = m_Login.Password;
                            LoadDirectory(path);
                        }
                        else
                        {
                            this.Close();
                        }
                    }));

                    break;

                case RequestResult.ListingFollows:
                    Log.DebugFormat("Remote host returned {0} File entries", files.Count);
                    RefreshListView(files);
                    break;

                case RequestResult.UnknownError:
                    Log.Info("Unknown Error trying to get file listing");
                    break;

                case RequestResult.InvalidArguments:
                    Log.Info("Invalid Arguments Passed to scp");
                    break;

                case RequestResult.SessionInvalid:
                    Log.Info("Session is invalid");
                    break;

                case RequestResult.CancelLogin:
                    Log.Info("User cancel login");
                    this.BeginInvoke(new MethodInvoker(this.Close));
                    break;

                default:
                    Log.InfoFormat("Unknown result '{0}'", result);
                    break;
                }
            };

            m_Transfer.BeginGetDirectoryListing(path, dirCallback);
            return(true);
        }
        private bool LoadDirectory(string path)
        {
            Logger.Log("Request directory listing for '{0}/{1}'", m_Session.SessionName, path);
            DirListingCallback dirCallback = delegate(RequestResult result, List <FileEntry> files)
            {
                switch (result)
                {
                case RequestResult.RetryAuthentication:
                    dlgLogin m_Login = new dlgLogin(m_Session);
                    if (m_Login.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        m_Session.Username = m_Login.Username;
                        m_Session.Password = m_Login.Password;
                        LoadDirectory(path);
                    }
                    break;

                case RequestResult.ListingFollows:
                    Console.WriteLine("Remote host returned {0} File entries", files.Count);
                    RefreshListView(files);
                    break;

                case RequestResult.UnknownError:
                    Logger.Log("Unknown Error trying to get file listing");
                    break;

                case RequestResult.InvalidArguments:
                    Logger.Log("Invalid Arguments Passed to scp");
                    break;

                case RequestResult.SessionInvalid:
                    Logger.Log("Session is invalid");
                    break;

                default:
                    Logger.Log("Unknown result '{0}'", result);
                    break;
                }
            };

            m_Transfer.BeginGetDirectoryListing(path, dirCallback);
            return(true);
        }
Example #3
0
        public void BeginGetDirectoryListing(string path, DirListingCallback callback)
        {
            if (m_Session == null)
            {
                callback(RequestResult.SessionInvalid, null);
                return;
            }

            List <FileEntry> files        = new List <FileEntry>();
            Stopwatch        timeoutWatch = new Stopwatch();

            /*
             * Check that we have a username either stored from previous sessions, or loaded
             * from the registry. If PPK Authentication is being used that will override
             * any values entered in the login dialog
             */
            if (String.IsNullOrEmpty(m_Session.Username))
            {
                if (m_Login.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    m_Session.Username = m_Login.Username;
                    m_Session.Password = m_Login.Password;

                    if (m_Login.Remember)
                    {
                        m_Session.SaveToRegistry(); // passwords are *never* saved and stored permanently
                    }
                }
            }

            Thread threadListFiles = new Thread(delegate()
            {
                m_processDir = new Process();

                m_processDir.EnableRaisingEvents             = true;
                m_processDir.StartInfo.UseShellExecute       = false;
                m_processDir.StartInfo.RedirectStandardError = true;
                //m_processDir.StartInfo.RedirectStandardInput = true;
                m_processDir.StartInfo.RedirectStandardOutput = true;
                m_processDir.StartInfo.CreateNoWindow         = true;
                m_processDir.StartInfo.FileName = frmSuperPutty.PscpExe;
                // process the various options from the session object and convert them into arguments pscp can understand
                string args = "-ls "; // default arguments
                args       += (!String.IsNullOrEmpty(m_Session.PuttySession)) ? "-load \"" + m_Session.PuttySession + "\" " : "";
                args       += (!String.IsNullOrEmpty(m_Session.Password) && m_Session.Password.Length > 0) ? "-pw " + m_Session.Password + " " : "";
                args       += "-P " + m_Session.Port + " ";
                args       += (!String.IsNullOrEmpty(m_Session.Username)) ? m_Session.Username + "@" : "";
                args       += m_Session.Host + ":" + path;
                Logger.Log("Sending Command: '{0} {1}'", m_processDir.StartInfo.FileName, args);
                m_processDir.StartInfo.Arguments = args;

                /*
                 * Handle output from spawned pscp.exe process, handle any data received and parse
                 * any lines that look like a directory listing.
                 */
                m_processDir.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
                {
                    if (!String.IsNullOrEmpty(e.Data))
                    {
                        if (e.Data.Equals(PUTTY_ARGUMENTS_HELP_HEADER))
                        {
                            m_processDir.CancelOutputRead();
                            m_processDir.Kill();
                            return;
                        }
                        else if (e.Data.StartsWith("Listing directory "))
                        {
                            // This just tells us the current directory, however since we're the ones that requested it
                            // we already have this information. But this traps it so its not sent through the directory
                            // entry parser.
                        }
                        else if (e.Data.Equals(PUTTY_INTERACTIVE_AUTH) || e.Data.Contains("password: "******"Username/Password invalid or not sent");
                            callback(RequestResult.RetryAuthentication, null);
                        }
                        else
                        {
                            timeoutWatch.Reset();
                            lock (files)
                            {
                                FileEntry file;
                                if (TryParseFileLine(e.Data, out file))
                                {
                                    files.Add(file);
                                }

                                if (files.Count > 0)
                                {
                                    callback(RequestResult.ListingFollows, files);
                                }
                            }
                        }
                    }
                };

                m_processDir.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
                {
                    if (!String.IsNullOrEmpty(e.Data))
                    {
                        if (e.Data.Contains(PUTTY_NO_KEY))
                        {
                            m_processDir.CancelErrorRead();
                            m_processDir.Kill();
                            System.Windows.Forms.MessageBox.Show("The key of the host you are attempting to connect to has changed or is not cached \n" +
                                                                 "You must connect to this host with with a PuTTY ssh terminal to accept the key and store it in the cache", "Host Key not found or changed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop);
                        }
                        else
                        {
                            Logger.Log("Error Data:\n\t'{0}'", e.Data.TrimEnd());
                            // 'ssh_init: Host does not exist'
                        }
                    }
                };

                m_processDir.Exited += delegate(object sender, EventArgs e)
                {
                    if (m_processDir.ExitCode != 0)
                    {
                        Logger.Log("Process Exited (Failure): {0}", m_processDir.ExitCode);
                        callback(RequestResult.UnknownError, null);
                        if (m_PuttyClosed != null)
                        {
                            m_PuttyClosed(true);
                        }
                    }
                    else
                    {
                        Logger.Log("Process Exited: {0}", m_processDir.ExitCode);
                        if (m_PuttyClosed != null)
                        {
                            m_PuttyClosed(false);
                        }
                    }
                    m_DirIsBusy = false;
                };

                try
                {
                    m_processDir.Start();
                }
                catch (Win32Exception e)
                {
                    if (e.NativeErrorCode == 2) // File Not Found
                    {
                        Logger.Log(e);
                    }
                    else if (e.NativeErrorCode == 4) // Acess Denied
                    {
                        Logger.Log(e);
                    }
                }

                m_processDir.BeginErrorReadLine();
                m_processDir.BeginOutputReadLine();
                m_processDir.WaitForExit();
            });

            /* Only allow one directory list request at a time */
            if (!m_DirIsBusy)
            {
                m_DirIsBusy                  = true;
                threadListFiles.Name         = "List Remote Directory";
                threadListFiles.IsBackground = true;
                threadListFiles.Start();
            }
            else
            {
                return;
            }

            Thread timeoutThread = new Thread(delegate()
            {
                while (m_DirIsBusy)
                {
                    /*
                     * if no data received in 5 seconds we'll stop the process,
                     * This allows us to capture any interactive prompts/messages
                     * sent to us by putty.
                     */
                    if (timeoutWatch.Elapsed.Seconds >= 5)
                    {
                        Logger.Log("Timeout after {0} seconds", timeoutWatch.Elapsed.Seconds);

                        if (!m_processDir.HasExited)
                        {
                            m_processDir.Kill();
                        }
                        m_processDir.CancelErrorRead();
                        m_processDir.CancelOutputRead();
                        return;
                    }
                    Thread.Sleep(1000);
                }
            });

            timeoutThread.Name         = "Timeout Watcher";
            timeoutThread.IsBackground = true;
            timeoutThread.Start();
            timeoutWatch.Start();
        }
Example #4
0
        public void BeginGetDirectoryListing(string path, DirListingCallback callback)
        {
            if (m_Session == null)
            {
                callback(RequestResult.SessionInvalid, null);
                return;
            }

            List<FileEntry> files = new List<FileEntry>();
            Stopwatch timeoutWatch = new Stopwatch();

            /*
             * Check that we have a username either stored from previous sessions, or loaded
             * from the registry. If PPK Authentication is being used that will override
             * any values entered in the login dialog
             */
            if (String.IsNullOrEmpty(m_Session.Username))
            {
                if (m_Login.ShowDialog(SuperPuTTY.MainForm) == System.Windows.Forms.DialogResult.OK)
                {
                    m_Session.Username = m_Login.Username;
                    m_Session.Password = m_Login.Password;

                    if (m_Login.Remember)
                    {
                        //Session.SaveToRegistry(); // passwords are *never* saved and stored permanently
                        SuperPuTTY.SaveSessions();
                    }
                }
                else
                {
                    Logger.Log("Cancel connection");
                    callback(RequestResult.CancelLogin, null);
                }
            }

            Thread threadListFiles = new Thread(delegate()
            {
                m_processDir = new Process();

                m_processDir.EnableRaisingEvents = true;
                m_processDir.StartInfo.UseShellExecute = false;
                m_processDir.StartInfo.RedirectStandardError = true;
                //m_processDir.StartInfo.RedirectStandardInput = true;
                m_processDir.StartInfo.RedirectStandardOutput = true;
                m_processDir.StartInfo.CreateNoWindow = true;
                m_processDir.StartInfo.FileName = SuperPuTTY.Settings.PscpExe;
                // process the various options from the session object and convert them into arguments pscp can understand
                string args = MakeArgs(m_Session, true, path);
                Logger.Log("Sending Command: '{0} {1}'", m_processDir.StartInfo.FileName, MakeArgs(m_Session, false, path));
                m_processDir.StartInfo.Arguments = args;
                /*
                 * Handle output from spawned pscp.exe process, handle any data received and parse
                 * any lines that look like a directory listing.
                 */
                m_processDir.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
                {
                    if (!String.IsNullOrEmpty(e.Data))
                    {
                        if (e.Data.Equals(PUTTY_ARGUMENTS_HELP_HEADER))
                        {
                            m_processDir.CancelOutputRead();
                            m_processDir.Kill();
                            return;
                        }
                        else if (e.Data.StartsWith("Listing directory "))
                        {
                            // This just tells us the current directory, however since we're the ones that requested it
                            // we already have this information. But this traps it so its not sent through the directory
                            // entry parser.
                        }
                        else if (e.Data.Equals(PUTTY_INTERACTIVE_AUTH) || e.Data.Contains("password: "******"Username/Password invalid or not sent");
                            callback(RequestResult.RetryAuthentication, null);
                        }
                        else
                        {
                            timeoutWatch.Reset();
                            lock (files)
                            {
                                FileEntry file;
                                if (TryParseFileLine(e.Data, out file))
                                {
                                    files.Add(file);
                                }

                                if (files.Count > 0)
                                {
                                    callback(RequestResult.ListingFollows, files);
                                }
                            }
                        }
                    }
                };

                m_processDir.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e)
                {
                    if (!String.IsNullOrEmpty(e.Data))
                    {
                        if (e.Data.Contains(PUTTY_NO_KEY))
                        {
                            m_processDir.CancelErrorRead();
                            m_processDir.Kill();
                            System.Windows.Forms.MessageBox.Show("The key of the host you are attempting to connect to has changed or is not cached \n" +
                                "You must connect to this host with with a PuTTY ssh terminal to accept the key and store it in the cache", "Host Key not found or changed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop);
                        }
                        else
                        {
                            Logger.Log("Error Data:\n\t'{0}'", e.Data.TrimEnd());
                            // 'ssh_init: Host does not exist'
                        }
                    }
                };

                m_processDir.Exited += delegate(object sender, EventArgs e)
                {
                    if (m_processDir.ExitCode != 0)
                    {
                        Logger.Log("Process Exited (Failure): {0}", m_processDir.ExitCode);
                        callback(RequestResult.UnknownError, null);
                        if (m_PuttyClosed != null)
                            m_PuttyClosed(true);
                    }
                    else
                    {
                        Logger.Log("Process Exited: {0}", m_processDir.ExitCode);
                        if (m_PuttyClosed != null)
                            m_PuttyClosed(false);
                    }
                    m_DirIsBusy = false;
                };

                try
                {
                    m_processDir.Start();
                }
                catch (Win32Exception e)
                {
                    if (e.NativeErrorCode == 2) // File Not Found
                    {
                        Logger.Log(e);
                    }
                    else if (e.NativeErrorCode == 4) // Acess Denied
                    {
                        Logger.Log(e);
                    }
                }

                m_processDir.BeginErrorReadLine();
                m_processDir.BeginOutputReadLine();
                m_processDir.WaitForExit();
            });

            /* Only allow one directory list request at a time */
            if (!m_DirIsBusy)
            {
                m_DirIsBusy = true;
                threadListFiles.Name = "List Remote Directory";
                threadListFiles.IsBackground = true;
                threadListFiles.Start();
            }
            else
            {
                return;
            }

            Thread timeoutThread = new Thread(delegate()
            {
                while (m_DirIsBusy)
                {
                    /*
                     * if no data received in 5 seconds we'll stop the process,
                     * This allows us to capture any interactive prompts/messages
                     * sent to us by putty.
                     */
                    if (timeoutWatch.Elapsed.Seconds >= 5)
                    {
                        Logger.Log("Timeout after {0} seconds", timeoutWatch.Elapsed.Seconds);

                        if (!m_processDir.HasExited)
                        {
                            m_processDir.Kill();
                        }
                        m_processDir.CancelErrorRead();
                        m_processDir.CancelOutputRead();
                        return;
                    }
                    Thread.Sleep(1000);
                }
            });
            timeoutThread.Name = "Timeout Watcher";
            timeoutThread.IsBackground = true;
            timeoutThread.Start();
            timeoutWatch.Start();
        }