/// <summary> /// Main method of the session thread. /// Reads commands and executes them. /// </summary> private void Work() { if (logHandler != null) { logHandler.NewControlConnection(); } try { if (!authHandler.AllowControlConnection()) { Respond(421, "Control connection refused."); // first flush, then close controlSocket.Shutdown(SocketShutdown.Both); controlSocket.Close(); return; } Respond(220, String.Format("This is mooftpserv v{0}. {1}", LIB_VERSION, GetRandomText(HELLO_TEXT))); // allow anonymous login? if (authHandler.AllowLogin(null, null)) { loggedIn = true; } while (controlSocket.Connected) { string verb; string args; if (!ReadCommand(out verb, out args)) { if (controlSocket.Connected) { // assume clean disconnect if there are no buffered bytes if (cmdRcvBytes != 0) { Respond(500, "Failed to read command, closing connection."); } controlSocket.Close(); } break; } else if (verb.Trim() == "") { // ignore empty lines continue; } try { if (loggedIn) { ProcessCommand(verb, args); } else if (verb == "QUIT") // QUIT should always be allowed { Respond(221, "Bye."); // first flush, then close controlSocket.Shutdown(SocketShutdown.Both); controlSocket.Close(); } else { HandleAuth(verb, args); } } catch (Exception ex) { Respond(500, ex); } } } catch (Exception) { // catch any uncaught stuff, the server should not throw anything } finally { if (controlSocket.Connected) { controlSocket.Close(); } if (logHandler != null) { logHandler.ClosedControlConnection(); } threadAlive = false; } }