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); }
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(); }
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(); }