/// <summary> /// Worker thread for remove directory /// </summary> private void RMDThread() { if (RequestPath.Length < 2) { Debug.Print("the path is not long enough"); throw new ArgumentException("The path is not a directory"); } else if (RequestPath[RequestPath.Length - 1] != "") { // the path is a directory Debug.Print("the path does not lead to a directory"); throw new ArgumentException("The path is not a directory"); } try { string command; int responseNumber; if (RequestPath.Length > 2) { command = "CWD "; for (int i = 0; i < RequestPath.Length - 2; i++) { command += RequestPath[i] + "/"; } command += "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 250) { // change directory failed return; } } command = "RMD " + RequestPath[RequestPath.Length - 2] + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 250) { Debug.Print("cannot remove directory with wrong number: " + responseNumber.ToString()); if (responseNumber == 550) { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } else { m_StatusCode = FTPStatusCode.CommandFailed; } return; } } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Deleting directory fail due to connection problem."); } }
/// <summary> /// Logging into the ftp server /// </summary> /// <returns> /// -1: unknown errors or exceptions happened /// 0: login succeed /// >0: reply code tells why server rejects the login process /// </returns> private int Login() { string command = null; byte[] dataBuffer = new byte[1000]; int responseNumber = 0; m_StatusCode = FTPStatusCode.NotLoggedIn; try { CommandSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); CommandSocket.ReceiveTimeout = m_CommandTimeout; IPAddress hostIP = IPAddress.Parse(ServerIP); CommandSocket.Connect(new IPEndPoint(hostIP, ServerPort)); responseNumber = WaitResponse(); if (responseNumber != 220) { // server not ready for new user login return(responseNumber); } command = "USER " + m_Credential.UserName + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 331) { // user name is not allowed return(responseNumber); } command = "PASS " + m_Credential.Password + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 230) { // password does not match return(responseNumber); } m_StatusCode = FTPStatusCode.LoggedInProceed; responseNumber = 0; } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Login fail due to connection problem."); } return(responseNumber); }
/// <summary> /// parse the response number to a status code /// </summary> /// <param name="responseNumber"></param> /// <returns> /// true if response number is less than 400 /// </returns> private bool SetStatusCode(int responseNumber) { if (responseNumber >= 500) { Debug.Print(Method + " with wrong number: " + responseNumber.ToString()); if (responseNumber == 502) { m_StatusCode = FTPStatusCode.CommandNotImplemented; } else if (responseNumber == 550) { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } else if (responseNumber == 553) { m_StatusCode = FTPStatusCode.FilenameNotAllowed; } else { m_StatusCode = FTPStatusCode.CommandFailed; } return(false); } else if (responseNumber >= 400) { Debug.Print(Method + " with wrong number: " + responseNumber.ToString()); if (responseNumber == 452) { m_StatusCode = FTPStatusCode.InsufficientSpace; } else { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } return(false); } else { return(true); } }
/// <summary> /// Functionality to run LIST scenario /// </summary> private void LISTThread() { if (RequestPath[RequestPath.Length - 1] != "") { // the path is a directory Debug.Print("the path does not lead to a directory"); throw new ArgumentException("The path is not a directory"); } try { string command = "CWD "; for (int i = 0; i < RequestPath.Length - 1; i++) { command += RequestPath[i] + "/"; } command += "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); int responseNumber = WaitResponse(); if (responseNumber != 250) { // change directory failed m_StatusCode = FTPStatusCode.CommandFailed; return; } using (Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { ConfigureListenSocket(listenSocket); FTPActivePort = (listenSocket.LocalEndPoint as IPEndPoint).Port; command = "PORT " + FormatFTPAddress(FTPActiveAddress, FTPActivePort) + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); while (responseNumber == 230) { responseNumber = WaitResponse(); } if (responseNumber != 200) { Debug.Print("port with wrong number: " + responseNumber.ToString()); m_StatusCode = FTPStatusCode.CommandFailed; return; } CommandSocket.Send(Encoding.UTF8.GetBytes("LIST\r\n")); responseNumber = WaitResponse(); if (!SetStatusCode(responseNumber)) { return; } using (Timer timer = new Timer(TimerCallback, null, m_DataTimeout, -1)) { DataSocket = listenSocket.Accept(); } DataSocketReady = true; m_DataStream = new NetworkStream(DataSocket); m_FtpResponse = new FtpWebResponse(m_DataStream); m_StreamReady.Set(); responseNumber = WaitResponse(-1); TransmissionFinished = true; if (responseNumber != 226) { Debug.Print("list end with wrong number: " + responseNumber.ToString()); m_StatusCode = FTPStatusCode.CommandFailed; return; } m_StatusCode = FTPStatusCode.CommandProceed; //while (!m_RequestClosed) //{ // // do not release the resource until the request is closed //} m_StatusCode = FTPStatusCode.ClosingData; } } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Downloading fail due to connection problem."); } }
/// <summary> /// Worker thread to rename a file or directory /// </summary> private void RenameThread() { if (RenameTo == null) { Debug.Print("New name is not selected"); throw new ArgumentNullException("New name is not selected"); } int oldIndex; if (RequestPath[RequestPath.Length - 1] == "") { throw new WebException("The requested URI is invalid for this FTP command."); } else { oldIndex = RequestPath.Length - 1; } try { string command = "CWD "; for (int i = 0; i < oldIndex; i++) { command += RequestPath[i] + "/"; } command += "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); int responseNumber = WaitResponse(); if (responseNumber != 250) { // change directory failed m_StatusCode = FTPStatusCode.CommandFailed; return; } command = "RNFR " + RequestPath[oldIndex] + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 350) { Debug.Print("REFR fail with wrong number: " + responseNumber.ToString()); if (responseNumber == 550) { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } else { m_StatusCode = FTPStatusCode.CommandFailed; } return; } command = "RNTO " + RenameTo + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 250) { Debug.Print("RETO fail with wrong number: " + responseNumber.ToString()); m_StatusCode = FTPStatusCode.CommandFailed; return; } } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Renaming fail due to connection problem."); } }
/// <summary> /// Worker thread for delete file /// </summary> private void DELEThread() { if (RequestPath[RequestPath.Length - 1] == "") { // the path is a directory Debug.Print("the path leads to a directory"); throw new ArgumentException("The path is a directory"); } try { string command = "CWD "; for (int i = 0; i < RequestPath.Length - 1; i++) { command += RequestPath[i] + "/"; } command += "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); int responseNumber = WaitResponse(); if (responseNumber != 250) { // change directory failed m_StatusCode = FTPStatusCode.CommandFailed; return; } command = "DELE " + RequestPath[RequestPath.Length - 1] + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 250) { Debug.Print("deletion fail with wrong number: " + responseNumber.ToString()); if (responseNumber == 550) { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } else { m_StatusCode = FTPStatusCode.CommandFailed; } return; } } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Deleting file fail due to connection problem."); } }
/// <summary> /// Worker thread for make directory /// </summary> private void MKDThread() { if (RequestPath.Length < 2) { Debug.Print("the path is not long enough"); throw new ArgumentException("The path is not a directory"); } else if (RequestPath[RequestPath.Length - 1] != "") { // the path is a directory Debug.Print("the path does not lead to a directory"); throw new ArgumentException("The path is not a directory"); } try { string command; int responseNumber; // need to change directory if (RequestPath.Length > 2) { command = "CWD "; for (int i = 0; i < RequestPath.Length - 2; i++) { command += RequestPath[i] + "/"; } command += "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 250) { // change directory failed m_StatusCode = FTPStatusCode.CommandFailed; return; } } command = "MKD " + RequestPath[RequestPath.Length - 2] + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 257) { Debug.Print("cannot create directory with wrong number: " + responseNumber.ToString()); m_StatusCode = FTPStatusCode.CommandFailed; return; } } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Making directory fail due to connection problem."); } }
/// <summary> /// Logging into the ftp server /// </summary> /// <returns> /// -1: unknown errors or exceptions happened /// 0: login succeed /// >0: reply code tells why server rejects the login process /// </returns> private int Login() { string command = null; byte[] dataBuffer = new byte[1000]; int responseNumber = 0; m_StatusCode = FTPStatusCode.NotLoggedIn; try { CommandSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); CommandSocket.ReceiveTimeout = m_CommandTimeout; IPAddress hostIP = IPAddress.Parse(ServerIP); CommandSocket.Connect(new IPEndPoint(hostIP, ServerPort)); responseNumber = WaitResponse(); if (responseNumber != 220) { // server not ready for new user login return responseNumber; } command = "USER " + m_Credential.UserName + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 331) { // user name is not allowed return responseNumber; } command = "PASS " + m_Credential.Password + "\r\n"; CommandSocket.Send(Encoding.UTF8.GetBytes(command)); responseNumber = WaitResponse(); if (responseNumber != 230) { // password does not match return responseNumber; } m_StatusCode = FTPStatusCode.LoggedInProceed; responseNumber = 0; } catch (SocketException se) { Debug.Print(se.Message); throw new WebException("Login fail due to connection problem."); } return responseNumber; }
/// <summary> /// parse the response number to a status code /// </summary> /// <param name="responseNumber"></param> /// <returns> /// true if response number is less than 400 /// </returns> private bool SetStatusCode(int responseNumber) { if (responseNumber >= 500) { Debug.Print(Method + " with wrong number: " + responseNumber.ToString()); if (responseNumber == 502) { m_StatusCode = FTPStatusCode.CommandNotImplemented; } else if (responseNumber == 550) { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } else if (responseNumber == 553) { m_StatusCode = FTPStatusCode.FilenameNotAllowed; } else { m_StatusCode = FTPStatusCode.CommandFailed; } return false; } else if (responseNumber >= 400) { Debug.Print(Method + " with wrong number: " + responseNumber.ToString()); if (responseNumber == 452) { m_StatusCode = FTPStatusCode.InsufficientSpace; } else { m_StatusCode = FTPStatusCode.ResourceUnavailableOrBusy; } return false; } else { return true; } }