Using system;
Using system. net;
Using system. IO;
Using system. text;
Using system. net. Sockets;
Namespace ftplib
{
Public class ftpfactory
{
Private string
Remotehost, remotepath, remoteuser, remotepass, mes;
Private int remoteport, bytes;
Private socket clientsocket;
Private int retvalue;
Private Boolean debug;
Private Boolean logined;
Private string reply;
Private Static int block_size = 512;
Byte [] buffer = new byte [block_size];
Encoding ASCII = encoding. ASCII;
Public ftpfactory ()
{
Remotehost = "localhost ";
Remotepath = ".";
Remoteuser = "anonymous ";
Remotepass = "jaimon@school2000.co.uk ";
Remoteport = 21;
DEBUG = false;
Logined = false;
}
///
/// Set the name of the FTP server to connect.
///
/// Server name
Public void setremotehost (string remotehost)
{
This. remotehost = remotehost;
}
///
/// Return the name of the current FTP server.
///
/// Server name
Public String getremotehost ()
{
Return remotehost;
}
///
/// Set the port number to use for FTP.
///
/// Port number
Public void setremoteport (INT remoteport)
{
This. remoteport = remoteport;
}
///
/// Return the current port number.
///
/// Current port number
Public int getremoteport ()
{
Return remoteport;
}
///
/// Set the remote directory path.
///
/// The remote directory path
Public void setremotepath (string remotepath)
{
This. remotepath = remotepath;
}
///
/// Return the current remote directory path.
///
/// The current remote directory path.
Public String getremotepath ()
{
Return remotepath;
}
///
/// Set the user name to use for logging into the remote server.
///
/// Username
Public void setremoteuser (string remoteuser)
{
This. remoteuser = remoteuser;
}
///
/// Set the password to user for logging into the remote server.
///
/// Password
Public void setremotepass (string remotepass)
{
This. remotepass = remotepass;
}
///
/// Return a string array containing the remote directory's file list.
///
///
///
Public String [] getfilelist (string mask)
{
If (! Logined)
{
Login ();
}
Socket csocket = createdatasocket ();
Sendcommand ("NLST" + mask );
If (! (Retvalue = 150 | retvalue = 125 ))
{
Throw new ioexception (reply. substring (4 ));
}
MEs = "";
While (true)
{
Int bytes = csocket. Receive (buffer, buffer. length, 0 );
MES + = system. Text. encoding. getencoding ("gb2312"). getstring (buffer, 0, bytes );
If (Bytes <buffer. length)
{
Break;
}
}
Char [] seperator = {'/N '};
String [] mess = mes. Split (seperator );
Csocket. Close ();
Readreply ();
If (retvalue! = 226)
{
Throw new ioexception (reply. substring (4 ));
}
Return mess;
}
///
/// Return the size of a file.
///
///
///
Public long getfilesize (string filename)
{
If (! Logined)
{
Login ();
}
Sendcommand ("size" + filename );
Long size = 0;
If (retvalue = 213)
{
Size = int64.parse (reply. substring (4 ));
}
Else
{
Throw new ioexception (reply. substring (4 ));
}
Return size;
}
///
/// Login to the remote server.
///
Public void login ()
{
Clientsocket = new
Socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP );
Ipendpoint Ep = new
Ipendpoint (DNS. Resolve (remotehost). Addresslist [0], remoteport );
Try
{
Clientsocket. Connect (EP );
}
Catch (exception)
{
Throw new ioexception ("couldn't connect to remote server ");
}
Readreply ();
If (retvalue! = 220)
{
Close ();
Throw new ioexception (reply. substring (4 ));
}
If (Debug)
Console. writeline ("user" + remoteuser );
Sendcommand ("user" + remoteuser );
If (! (Retvalue = 331 | retvalue = 230 ))
{
Cleanup ();
Throw new ioexception (reply. substring (4 ));
}
If (retvalue! = 230)
{
If (Debug)
Console. writeline ("Pass XXX ");
Sendcommand ("pass" + remotepass );
If (! (Retvalue = 230 | retvalue = 202 ))
{
Cleanup ();
Throw new ioexception (reply. substring (4 ));
}
}
Logined = true;
Console. writeline ("connected to" + remotehost );
Chdir (remotepath );
}
///
/// If the value of mode is true, set binary mode for downloads.
/// Else, set ASCII mode.
///
///
Public void setbinarymode (Boolean Mode)
{
If (Mode)
{
Sendcommand ("type I ");
}
Else
{
Sendcommand ("Type ");
}
If (retvalue! = 200)
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Download a file to the Assembly's local directory,
/// Keeping the same file name.
///
///
Public void download (string remfilename)
{
Download (remfilename, "", false );
}
///
/// Download a remote file to the Assembly's local directory,
/// Keeping the same file name, and set the resume flag.
///
///
///
Public void download (string remfilename, Boolean resume)
{
Download (remfilename, "", resume );
}
///
/// Download a remote file to a local file name which can include
/// A path. The local file name will be created or overwritten,
/// But the path must exist.
///
///
///
Public void download (string remfilename, string locfilename)
{
Download (remfilename, locfilename, false );
}
///
/// Download a remote file to a local file name which can include
/// A path, and set the resume flag. The local file name will be
/// Created or overwritten, but the path must exist.
///
///
///
///
Public void download (string remfilename, string locfilename, Boolean resume)
{
If (! Logined)
{
Login ();
}
Setbinarymode (true );
Console. writeline ("downloading file" + remfilename + "from" + remotehost + "/" + remotepath );
If (locfilename. Equals (""))
{
Locfilename = remfilename;
}
If (! File. exists (locfilename ))
{
Stream ST = file. Create (locfilename );
St. Close ();
}
Filestream output = new
Filestream (locfilename, filemode. Open );
Socket csocket = createdatasocket ();
Long offset = 0;
If (resume)
{
Offset = output. length;
If (Offset> 0)
{
Sendcommand ("rest" + offset );
If (retvalue! = 350)
{
// Throw new ioexception (reply. substring (4 ));
// Some servers may not support resuming.
Offset = 0;
}
}
If (Offset> 0)
{
If (Debug)
{
Console. writeline ("seeking to" + offset );
}
Long NPOs = output. Seek (offset, seekorigin. Begin );
Console. writeline ("New Pos =" + NPOs );
}
}
Sendcommand ("retr" + remfilename );
If (! (Retvalue = 150 | retvalue = 125 ))
{
Throw new ioexception (reply. substring (4 ));
}
While (true)
{
Bytes = csocket. Receive (buffer, buffer. length, 0 );
Output. Write (buffer, 0, bytes );
If (Bytes <= 0)
{
Break;
}
}
Output. Close ();
If (csocket. Connected)
{
Csocket. Close ();
}
Console. writeline ("");
Readreply ();
If (! (Retvalue = 226 | retvalue = 250 ))
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Upload a file.
///
///
Public void upload (string filename)
{
Upload (filename, false );
}
///
/// Upload a file and set the resume flag.
///
///
///
Public void upload (string filename, Boolean resume)
{
If (! Logined)
{
Login ();
}
Socket csocket = createdatasocket ();
Long offset = 0;
If (resume)
{
Try
{
Setbinarymode (true );
Offset = getfilesize (filename );
}
Catch (exception)
{
Offset = 0;
}
}
If (Offset> 0)
{
Sendcommand ("rest" + offset );
If (retvalue! = 350)
{
// Throw new ioexception (reply. substring (4 ));
// Remote server may not support resuming.
Offset = 0;
}
}
Sendcommand ("stor" + path. getfilename (filename ));
If (! (Retvalue = 125 | retvalue = 150 ))
{
Throw new ioexception (reply. substring (4 ));
}
// Open input stream to read source file
Filestream input = new
Filestream (filename, filemode. Open );
If (offset! = 0)
{
If (Debug)
{
Console. writeline ("seeking to" + offset );
}
Input. Seek (offset, seekorigin. Begin );
}
Console. writeline ("uploading file" + filename + "to" + remotepath );
While (Bytes = input. Read (buffer, 0, buffer. Length)> 0)
{
Csocket. Send (buffer, bytes, 0 );
}
Input. Close ();
Console. writeline ("");
If (csocket. Connected)
{
Csocket. Close ();
}
Readreply ();
If (! (Retvalue = 226 | retvalue = 250 ))
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Delete a file from the remote FTP server.
///
///
Public void deleteremotefile (string filename)
{
If (! Logined)
{
Login ();
}
Sendcommand ("DELE" + filename );
If (retvalue! = 250)
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Rename a file on the remote FTP server.
///
///
///
Public void renameremotefile (string oldfilename, string
Newfilename)
{
If (! Logined)
{
Login ();
}
Sendcommand ("RNFR" + oldfilename );
If (retvalue! = 350)
{
Throw new ioexception (reply. substring (4 ));
}
// Known problem
// RNTO will not take care of existing file.
// I. e. It will overwrite if newfilename exist
Sendcommand ("RNTO" + newfilename );
If (retvalue! = 250)
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Create a directory on the remote FTP server.
///
///
Public void mkdir (string dirname)
{
If (! Logined)
{
Login ();
}
Sendcommand ("MKD" + dirname );
If (retvalue! = 250)
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Delete a directory on the remote FTP server.
///
///
Public void rmdir (string dirname)
{
If (! Logined)
{
Login ();
}
Sendcommand ("RMD" + dirname );
If (retvalue! = 250)
{
Throw new ioexception (reply. substring (4 ));
}
}
///
/// Change the current working directory on the remote FTP server.
///
///
Public void chdir (string dirname)
{
If (dirname. Equals ("."))
{
Return;
}
If (! Logined)
{
Login ();
}
Sendcommand ("CWD" + dirname );
If (retvalue! = 250)
{
Throw new ioexception (reply. substring (4 ));
}
This. remotepath = dirname;
Console. writeline ("Current directory is" + remotepath );
}
///
/// Close the FTP connection.
///
Public void close ()
{
If (clientsocket! = NULL)
{
Sendcommand ("quit ");
}
Cleanup ();
Console. writeline ("closing ...");
}
///
/// Set debug mode.
///
///
Public void setdebug (Boolean Debug)
{
This. DEBUG = debug;
}
Private void readreply ()
{
MEs = "";
Reply = Readline ();
Retvalue = int32.parse (reply. substring (0, 3 ));
}
Private void cleanup ()
{
If (clientsocket! = NULL)
{
Clientsocket. Close ();
Clientsocket = NULL;
}
Logined = false;
}
Private string Readline ()
{
While (true)
{
Bytes = clientsocket. Receive (buffer, buffer. length, 0 );
MES + = ASCII. getstring (buffer, 0, bytes );
If (Bytes <buffer. length)
{
Break;
}
}
Char [] seperator = {'/N '};
String [] mess = mes. Split (seperator );
If (mes. length> 2)
{
MEs = mess [mess. Length-2];
}
Else
{
MEs = mess [0];
}
If (! Mes. substring (3,1). Equals (""))
{
Return Readline ();
}
If (Debug)
{
For (int K = 0; k <mess. Length-1; k ++)
{
Console. writeline (mess [k]);
}
}
Return MES;
}
Private void sendcommand (string command)
{
Byte [] cmdbytes =
Encoding. ASCII. getbytes (command + "/R/N"). tochararray ());
Clientsocket. Send (cmdbytes, cmdbytes. length, 0 );
Readreply ();
}
Private socket createdatasocket ()
{
Sendcommand ("PASV ");
If (retvalue! = 227)
{
Throw new ioexception (reply. substring (4 ));
}
Int index1 = reply. indexof ('(');
Int index2 = reply. indexof (')');
String ipdata =
Reply. substring (index1 + 1, index2-index1-1 );
Int [] parts = new int [6];
Int Len = ipdata. length;
Int partcount = 0;
String Buf = "";
For (INT I = 0; I <Len & partcount <= 6; I ++)
{
Char CH = Char. parse (ipdata. substring (I, 1 ));
If (char. isdigit (CH ))
BUF + = CH;
Else if (Ch! = ',')
{
Throw new ioexception ("malformed PASV reply:" +
Reply );
}
If (CH = ',' | I + 1 = Len)
{
Try
{
Parts [partcount ++] = int32.parse (BUF );
Buf = "";
}
Catch (exception)
{
Throw new ioexception ("malformed PASV reply:" +
Reply );
}
}
}
String IPaddress = parts [0] + "." + parts [1] + "." +
Parts [2] + "." + parts [3];
Int Port = (parts [4] <8) + parts [5];
Socket S = new
Socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP );
Ipendpoint Ep = new
Ipendpoint (DNS. Resolve (IPaddress). Addresslist [0], Port );
Try
{
S. Connect (EP );
}
Catch (exception)
{
Throw new ioexception ("can't connect to remote server ");
}
Return S;
}
}
}
Example:
String ftpinfo [] = new string [] {"192.168.100.2", "wwg", "12345 "};
String dir = "softdown ";
Ftpfactory FF = new ftpfactory ();
Ff. setdebug (true );
Ff. setremotehost (ftpinfo [0]);
Ff. setremoteuser (ftpinfo [1]);
Ff. setremotepass (ftpinfo [2]);
Ff. login ();
Ff. chdir (@ DIR );
Ff. setbinarymode (true );
Ff. Close ();