/// <summary> /// Get the type of the OS at the server /// </summary> /// <returns> /// the type of server OS /// </returns> public string System() { string reply = control.SendCommand("SYST"); lastValidReply = control.ValidateReply(reply, "215"); return(lastValidReply.ReplyText); }
/// <summary> /// Get the help text for the specified command /// </summary> /// <param name="command"> name of the command to get help on /// </param> /// <returns> help text from the server for the supplied command /// /// </returns> public string Help(string command) { string reply = control.SendCommand("HELP " + command); string[] validCodes = new string[] { "211", "214" }; lastValidReply = control.ValidateReply(reply, validCodes); return(lastValidReply.ReplyText); }
/// <summary> /// Validate that the put() or get() was successful /// </summary> private void ValidateTransfer() { // check the control response string[] validCodes = new string[] { "226", "250" }; string reply = control.ReadReply(); lastValidReply = control.ValidateReply(reply, validCodes); }
/// <summary> /// Supply the user name to log into an account /// on the FTP server. Must be followed by the /// password() method - but we allow for /// </summary> /// <param name="user"> /// user name /// </param> public void User(string user) { string reply = control.SendCommand("USER " + user); // we allow for a site with no password - 230 response string[] validCodes = new string[] { "230", "331" }; lastValidReply = control.ValidateReply(reply, validCodes); }
/// <summary> /// Supplies the password for a previously supplied /// username to log into the FTP server. Must be /// preceeded by the user() method /// </summary> /// <param name="password"> /// user's password /// </param> public void Password(string password) { string reply = control.SendCommand("PASS " + password); // we allow for a site with no passwords (202) string[] validCodes = new string[] { "230", "202" }; lastValidReply = control.ValidateReply(reply, validCodes); }
/// <summary> /// Login into an account on the FTP server. This /// call completes the entire login process /// </summary> /// <param name="user"> /// user name /// </param> /// <param name="password"> /// user's password /// </param> public void Login(string user, string password) { string response = control.SendCommand("USER " + user); lastValidReply = control.ValidateReply(response, "331"); response = control.SendCommand("PASS " + password); lastValidReply = control.ValidateReply(response, "230"); }
/// <summary> /// Delete the specified remote working directory /// </summary> /// <param name="dir"> /// name of remote directory to delete /// </param> public void Rmdir(string dir) { string reply = control.SendCommand("RMD " + dir); // some servers return 257, technically incorrect but // we cater for it ... string[] validCodes = new string[] { "250", "257" }; lastValidReply = control.ValidateReply(reply, validCodes); }
/// <summary> /// Rename a file or directory /// </summary> /// <param name="from"> name of file or directory to rename /// </param> /// <param name="to"> intended name /// /// </param> public void Rename(string from, string to) { string reply = control.SendCommand("RNFR " + from); lastValidReply = control.ValidateReply(reply, "350"); reply = control.SendCommand("RNTO " + to); lastValidReply = control.ValidateReply(reply, "250"); }
/// <summary> /// List a directory's contents as an array of strings. A detailed /// listing is available, otherwise just filenames are provided. /// The detailed listing varies in details depending on OS and /// FTP server. Note that a full listing can be used on a file /// name to obtain information about a file /// </summary> /// <param name="dirname"> /// name of directory (<b>not</b> a file mask) /// </param> /// <param name="full"> /// true if detailed listing required false otherwise /// </param> /// <returns> /// an array of directory listing strings /// </returns> public string[] Dir(string dirname, bool full) { // set up data channel data = control.CreateDataSocket(connectMode); // send the retrieve command string command = full?"LIST ":"NLST "; if (dirname != null) { command += dirname; } // some FTP servers bomb out if NLST has whitespace appended command = command.Trim(); string reply = control.SendCommand(command); // check the control response. wu-ftp returns 550 if the // directory is empty, so we handle 550 appropriately string[] validCodes1 = new string[] { "125", "150", "550" }; lastValidReply = control.ValidateReply(reply, validCodes1); // an empty array of files for 550 string[] result = new string[0]; // a normal reply ... extract the file list if (!lastValidReply.ReplyCode.Equals("550")) { // get an character input stream to read data from . StreamReader reader = new StreamReader(GetDataStream()); // read a line at a time ArrayList lines = new ArrayList(); string line = null; while ((line = reader.ReadLine()) != null) { lines.Add(line); } try { reader.Close(); } catch (IOException) { } // check the control response string[] validCodes2 = new string[] { "226", "250" }; reply = control.ReadReply(); lastValidReply = control.ValidateReply(reply, validCodes2); // empty array is default if (lines.Count > 0) { result = (string[])lines.ToArray(typeof(string)); } } return(result); }
/// <summary> /// Issue arbitrary ftp commands to the FTP server. /// </summary> /// <param name="command"> /// ftp command to be sent to server /// </param> /// <param name="validCodes"> /// valid return codes for this command /// </param> public void Quote(string command, string[] validCodes) { string reply = control.SendCommand(command); // allow for no validation to be supplied if (validCodes != null && validCodes.Length > 0) { lastValidReply = control.ValidateReply(reply, validCodes); } }
/// <summary> /// Get modification time for a remote file /// </summary> /// <param name="remoteFile"> /// name of remote file /// </param> /// <returns> /// modification time of file as a date /// </returns> public DateTime ModTime(string remoteFile) { string reply = control.SendCommand("MDTM " + remoteFile); lastValidReply = control.ValidateReply(reply, "213"); // parse the reply string ... DateTime ts = DateTime.ParseExact(lastValidReply.ReplyText, dtFormat, null); return(ts); }
/// <summary> /// Request to the server that the get is set up /// </summary> /// <param name="remoteFile"> /// name of remote file /// </param> private void InitGet(string remoteFile) { // set up data channel data = control.CreateDataSocket(connectMode); // send the retrieve command string reply = control.SendCommand("RETR " + remoteFile); // Can get a 125 or a 150 string[] validCodes1 = new string[] { "125", "150" }; lastValidReply = control.ValidateReply(reply, validCodes1); }
/// <summary> /// Quit the FTP session /// </summary> public void Quit() { try { string reply = control.SendCommand("QUIT"); string[] validCodes = new string[] { "221", "226" }; lastValidReply = control.ValidateReply(reply, validCodes); } finally { // ensure we clean up the connection control.Logout(); control = null; } }
/// <summary> /// Request the server to set up the put /// </summary> /// <param name="remoteFile"> name of remote file in /// current directory /// </param> /// <param name="append"> true if appending, false otherwise /// /// </param> private void InitPut(string remoteFile, bool append) { // set up data channel data = control.CreateDataSocket(connectMode); // send the command to store string cmd = append ? "APPE ":"STOR "; string reply = control.SendCommand(cmd + remoteFile); // Can get a 125 or a 150 string[] validCodes = new string[] { "125", "150" }; lastValidReply = control.ValidateReply(reply, validCodes); }
/// <summary> Validate the response the host has supplied against the /// expected reply. If we get an unexpected reply we throw an /// exception, setting the message to that returned by the /// FTP server /// /// </summary> /// <param name="reply"> the entire reply string we received /// </param> /// <param name="expectedReplyCode"> the reply we expected to receive /// /// /// </param> internal FTPReply ValidateReply(string reply, string expectedReplyCode) { // all reply codes are 3 chars long string replyCode = reply.Substring(0, 3); string replyText = reply.Substring(4); FTPReply replyObj = new FTPReply(replyCode, replyText); if (replyCode.Equals(expectedReplyCode)) { return(replyObj); } // if unexpected reply, throw an exception throw new FTPException(replyText, replyCode); }
/// <summary> /// Validate the response the host has supplied against the /// expected reply. If we get an unexpected reply we throw an /// exception, setting the message to that returned by the /// FTP server /// </summary> /// <param name="reply"> /// the entire reply string we received /// </param> /// <param name="expectedReplyCodes"> /// array of expected replies /// </param> /// <returns> /// an object encapsulating the server's reply /// </returns> internal FTPReply ValidateReply(string reply, string[] expectedReplyCodes) { // all reply codes are 3 chars long string replyCode = reply.Substring(0, 3); string replyText = reply.Substring(4); FTPReply replyObj = new FTPReply(replyCode, replyText); for (int i = 0; i < expectedReplyCodes.Length; i++) { if (replyCode.Equals(expectedReplyCodes[i])) { return(replyObj); } } // got this far, not recognised throw new FTPException(replyText, replyCode); }
/// <summary> /// Run a site-specific command on the /// server. Support for commands is dependent /// on the server /// </summary> /// <param name="command"> /// the site command to run /// </param> /// <returns> true if command ok, false if /// command not implemented /// </returns> public bool Site(string command) { // send the retrieve command string reply = control.SendCommand("SITE " + command); // Can get a 200 (ok) or 202 (not impl). Some // FTP servers return 502 (not impl) string[] validCodes = new string[] { "200", "202", "502" }; lastValidReply = control.ValidateReply(reply, validCodes); // return true or false? 200 is ok, 202/502 not // implemented if (reply.Substring(0, (3) - (0)).Equals("200")) { return(true); } else { return(false); } }
/// <summary> /// Get the current remote working directory /// </summary> /// <returns> /// the current working directory /// </returns> public string Pwd() { string reply = control.SendCommand("PWD"); lastValidReply = control.ValidateReply(reply, "257"); // get the reply text and extract the dir // listed in quotes, if we can find it. Otherwise // just return the whole reply string string text = lastValidReply.ReplyText; int start = text.IndexOf((System.Char) '"'); int end = text.LastIndexOf((System.Char) '"'); if (start >= 0 && end > start) { return(text.Substring(start + 1, (end) - (start + 1))); } else { return(text); } }
/// <summary> /// Delete the specified remote file /// </summary> /// <param name="remoteFile"> name of remote file to /// delete /// /// </param> public void Delete(string remoteFile) { string reply = control.SendCommand("DELE " + remoteFile); lastValidReply = control.ValidateReply(reply, "250"); }
/// <summary> /// Create the specified remote working directory /// </summary> /// <param name="dir"> /// name of remote directory to create /// </param> public void Mkdir(string dir) { string reply = control.SendCommand("MKD " + dir); lastValidReply = control.ValidateReply(reply, "257"); }
/// <summary> /// Change the remote working directory to /// that supplied /// </summary> /// <param name="dir"> name of remote directory to /// change to /// /// </param> public void Chdir(string dir) { string reply = control.SendCommand("CWD " + dir); lastValidReply = control.ValidateReply(reply, "250"); }