import java.net.*;
import java.io.*;
public class serverRichiesteFTP extends Thread
{
private static String LogFile="Azioni.log";
private static String workDir="c:\\Ftpdir";
private Socket connessione;
final int
porta_FTP_DTP=20;
final int
Porta_com=1188;
final int
Porta_dati=1189;
String nome_coordinatore=new String();
int remote_port=20;
File workingPath;
ListaFile serverReg=new ListaFile();
public serverRichiesteFTP()
{}
public serverRichiesteFTP(Socket in,ListaFile lf,String co)
{
connessione=in;
serverReg=lf;
nome_coordinatore=co;
}
public void
run()
{
ListaFile temp=new ListaFile();
String lista_file[]=new String[60];
String temp_lista[]=new String[60];
FileWriter scrittoreLog;
String messaggio=new String();
String client_remoto=new String();
String nome_utente=new String();
String password_utente=new String();
String mode_utente=new String();
String type_utente=new String();
boolean connesso;
try
{
scrittoreLog=new FileWriter(LogFile,true);
client_remoto=connessione.getInetAddress().toString();
System.out.println("Connessione
stabilita con "+client_remoto);
scrittoreLog.write("Connessione stabilita con "+client_remoto+"\r\n");
scrittoreLog.flush();
connesso=true;
workingPath=new
File(workDir);
//registro alcuni utenti
this.registraUtenti();
//preparazione alla
comunicazione
connessione.setTcpNoDelay(true);
//Timeout di tre minuti
//connessione.setSoTimeout(180000);
//attesa di 4 minuti
per inviare i dati prima della chiusura della socket
connessione.setSoLinger(true,240);
BufferedReader comandiIn=new BufferedReader(new InputStreamReader(connessione.getInputStream()));
PrintWriter comandiOut=new
PrintWriter(connessione.getOutputStream(),true);
//invio messaggio di
benvenuto
comandiOut.println("220
Benvenuto!");
scrittoreLog.write(client_remoto+": invio
messaggio di benvenuto\r\n");
scrittoreLog.flush();
while(connesso)
{
messaggio=comandiIn.readLine();
//visualizza la stringa ricevuta dal client
//System.out.println(messaggio);
//************************************************/
//GRUPPO DI COMANDI PER IL CONTROLLO DELL'
ACCESSO
//************************************************/
//COMANDO USER: riceve il nome utente
if(messaggio.startsWith("USER"))
{
//qualsiasi nome è
accettato, va verificata la password
comandiOut.println("331 User name
okay, need password.");
nome_utente=new String(messaggio.substring(4));
nome_utente=nome_utente.trim();
}
//COMANDO PASS: riceve la password dell'
utente
if(messaggio.startsWith("PASS"))
{
password_utente=new String(messaggio.substring(4));
password_utente=password_utente.trim();
if(leggi(new
Iscritto(nome_utente,password_utente)))
{
comandiOut.println("230 User logged
in, proceed.");
scrittoreLog.write("L\' utente
"+nome_utente+" si e\'
collegato\r\n");
System.out.println("L\' utente
"+nome_utente+" si e\'
collegato");
}
else
{
comandiOut.println("501 Wrong password.");
connesso=false;
}
}
//COMANDO QUIT: termina la sessione corrente
if(messaggio.startsWith("QUIT"))
{
connesso=false;
}
//COMANDO ACCT: identifica l' account
if(messaggio.startsWith("ACCT"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO REIN: termina la sessione per
l'account-utente attuale e richiede un nuovo accesso
if(messaggio.startsWith("REIN"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO SYST: serve per chiedere il tipo di
sistema operativo in uso sul server
if(messaggio.startsWith("SYST"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO NOOP: si invia semplicemente un OK
if(messaggio.startsWith("NOOP"))
{
comandiOut.println("200 OK.");
}
//**************************************************/
//GRUPPO DI COMANDI PER I PARAMETRI DI
TRASFERIMENTO
//**************************************************/
//COMANDO TYPE: indica se il trasferimento dei
dati è di tipo ASCII o BINARY
if(messaggio.startsWith("TYPE"))
{
//Gestire il comando
type_utente=new
String(messaggio.substring(4));
type_utente=type_utente.trim();
if(type_utente.equals("I"))
{
comandiOut.println("200 command
okay.");
}
else if
(type_utente.startsWith("A"))
{
comandiOut.println("200 command
okay.");
//comandiOut.println("504
command not implemented for that parameter.");
}
else if(type_utente.startsWith("E"))
{
comandiOut.println("504 command not
implemented for that parameter.");
}
else if(type_utente.startsWith("L"))
{
comandiOut.println("504 command not
implemented for that parameter.");
}
else
{
comandiOut.println("501 Syntax
error in parameters or arguments.");
}
}
//COMANDO MODE: specifica la modalità di
trasferimento dei file: STREAM, BLOCK o COMPRESSED
if(messaggio.startsWith("MODE"))
{
//Gestire il comando
mode_utente=new
String(messaggio.substring(4));
mode_utente=mode_utente.trim();
if(mode_utente.equals("S"))
{
comandiOut.println("200 ok");
}
else if(mode_utente.equals("B")||mode_utente.equals("C"))
{
comandiOut.println("504 command not
implemented for that parameter.");
}
else
{
comandiOut.println("501 Syntax
error in parameters or arguments.");
}
}
//COMANDO PORT: permette di definire il socket
lato client
if(messaggio.startsWith("PORT"))
{
int lng,lng1,lng2,ip1,ip2;
String
a1=new String();
String
a2=new String();
lng =
messaggio.length() - 1;
lng2 =
messaggio.lastIndexOf(",");
lng1 =
messaggio.lastIndexOf(",",lng2-1);
for(int i=lng1+1;i<lng2;i++)
{
a1 =
a1 + messaggio.charAt(i);
}
for(int i=lng2+1;i<=lng;i++)
{
a2 =
a2 + messaggio.charAt(i);
}
ip1 =
Integer.parseInt(a1);
ip2
=Integer.parseInt(a2);
remote_port
= ip1 * 16 *16 + ip2;
comandiOut.println("200 command
okay.");
}
//***********************************************/
//GRUPPO DI COMANDI PER IL TRASFERIMENTO DEI
FILE
//***********************************************/
//COMANDO RETR:
if(messaggio.startsWith("RETR"))
{
messaggio=messaggio.substring(4);
messaggio=messaggio.trim();
try
{
System.out.println("L\' utente
"+nome_utente+" ha richiesto
il file "+messaggio);
scrittoreLog.write("L\' utente
"+nome_utente+" ha richiesto
il file "+messaggio+"\r\n");
scrittoreLog.flush();
String
server_sorgente=new String();
boolean trovato=false;
boolean locale=false;
temp_lista=workingPath.list();
for(int j=0;j<temp_lista.length;j++)
{
if(temp_lista[j]==null)
{
break;
}
if(temp_lista[j].equals(messaggio))
{
locale=true;
trovato=true;
break;
}
}
//System.out.println("file
locale: "+locale);
synchronized(serverReg)
{
for(int j=0;((j<serverReg.lista_server.length)&&(!trovato));j++)
{
if(serverReg.lista_server[j]==null)
{
break;
}
for(int i=0;i<serverReg.lista_file_server[j].length;i++)
{
if(serverReg.lista_file_server[j][i]==null)break;
if(serverReg.lista_file_server[j][i].toString().equals(messaggio))
{
trovato=true;
server_sorgente=serverReg.lista_server[j];
break;
}
}//for
}//for
}//synchro
//System.out.println(trovato);System.out.println(server_sorgente);
if(trovato)
{
byte buffer[]=new byte[1024];
int i;
//procedura locale
if(locale)
{
try
{
comandiOut.println("150 Binary data
connection.");
Socket data_sock=new
Socket(connessione.getInetAddress(),remote_port,connessione.getLocalAddress(),porta_FTP_DTP);
OutputStream
data_out=data_sock.getOutputStream();
RandomAccessFile fileout=new
RandomAccessFile(workingPath+"/"+messaggio,"r");
while((i=fileout.read(buffer))!=-1)
{
data_out.write(buffer,0,i);
data_out.flush();
}
data_out.close();
comandiOut.println("226 transfer
complete.");
fileout.close();
data_sock.close();
}
catch(IOException e)
{
System.out.println(e);
System.out.println("Errore durante
RETR");
comandiOut.println("550 file
transfer error");
}
}
//procedura remota
else
{
try
{
Socket file_sock=new
Socket(server_sorgente,Porta_dati);
String risp=new String();
Integer porta_file;
ObjectOutputStream oos2=new
ObjectOutputStream(file_sock.getOutputStream());
ObjectInputStream ois2=new
ObjectInputStream(file_sock.getInputStream());
Socket data_sock=new Socket(connessione.getInetAddress(),remote_port);
OutputStream data_out=data_sock.getOutputStream();
oos2.writeObject("richiesta
file");
oos2.flush();
oos2.writeObject(messaggio);
oos2.flush();
risp=(String)ois2.readObject();
//System.out.println(risp);
if(risp.equals("trasferimento accordato"))
{
porta_file=(Integer)ois2.readObject();
ServerSocket
sock_in_file=new ServerSocket(porta_file.intValue());
oos2.writeObject("pronto");
oos2.flush();
file_sock.close();
file_sock.close();
ois2.close();
oos2.close();
Socket
sock_in_dati=sock_in_file.accept();
ObjectInputStream ois3=new
ObjectInputStream(sock_in_dati.getInputStream());
System.out.println("trasferimento
accordato da "+server_sorgente);
comandiOut.println("150 Binary data
connection.");
while((i=ois3.read(buffer))!=-1)
{
data_out.write(buffer,0,i);
data_out.flush();
}
data_out.close();
comandiOut.println("226 transfer
complete.");
System.out.println("trasferimento
completato");
ois3.close();
}
else
{
System.out.println("Trasferimento
non possibile");
comandiOut.println("550 file
transfer error");
ois2.close();
oos2.close();
}
}
catch(Exception e)
{
System.out.println(e);
System.out.println("Errore durante
RETR");
comandiOut.println("550 file transfer
error");
//gestisce la procedura per indicare che il
server non c'è più
if(e.getClass().toString().equals("class
java.net.ConnectException"))
{
try
{
Socket
sock_com=new
Socket(nome_coordinatore,Porta_com);
ObjectInputStream
ois=new
ObjectInputStream(sock_com.getInputStream());
ObjectOutputStream
oos=new
ObjectOutputStream(sock_com.getOutputStream());
String
mess=new String();
oos.writeObject("informazione");
oos.flush();
oos.writeObject(server_sorgente);
oos.flush();
mess=(String)ois.readObject();
System.out.println(mess);
oos.close();
ois.close();
}
catch(Exception ex)
{
System.out.println("Errore durante
l\' invio di informazioni al coordinatore");
System.out.println(ex);
}
}
}
}//else(server)
}//if(trovato)
else
{
System.out.println(nome_utente+": richiesto
file inesistente");
scrittoreLog.write(nome_utente+": richiesto
file inesistente\r\n");
scrittoreLog.flush();
comandiOut.println("550 file
unavailable");
}//else(trovato)
}
catch(FileNotFoundException
e)
{
System.out.println(nome_utente+": richiesto
file inesistente");
scrittoreLog.write(nome_utente+": richiesto
file inesistente\r\n");
scrittoreLog.flush();
comandiOut.println("550 file
unavailable");
}
}//fine comando RETR
//COMANDO STOR:
if(messaggio.startsWith("STOR"))
{
String
lista_file2[]=new String[60];
messaggio=messaggio.substring(4);
messaggio=messaggio.trim();
comandiOut.println("150 Binary data
connection.");
try
{
RandomAccessFile
filein=new
RandomAccessFile(workingPath+"/"+messaggio,"rw");
System.out.println("L\' utente
"+nome_utente+" invia il file
"+messaggio);
scrittoreLog.write("L\' utente
"+nome_utente+" invia il file
"+messaggio+"\r\n");
scrittoreLog.flush();
Socket
data_sock=new
Socket(connessione.getInetAddress(),remote_port,connessione.getLocalAddress(),porta_FTP_DTP);
InputStream
data_in=data_sock.getInputStream();
byte buffer[]=new byte[1024];
int i;
try
{
while((i=data_in.read(buffer))!=-1)
{
filein.write(buffer,0,i);
}
data_in.close();
comandiOut.println("226 transfer
complete.");
filein.close();
data_sock.close();
temp_lista=workingPath.list();
for(int cont=0;(cont<temp_lista.length);cont++)
{
if(temp_lista[cont]==null)break;
lista_file2[cont]=temp_lista[cont];
}
//aggiorno
la lista in locale
synchronized(serverReg)
{
for(int j=0;j<serverReg.lista_server.length;j++)
{
if(serverReg.lista_server[j]==null)break;
if(serverReg.lista_server[j].equals(connessione.getLocalAddress().getHostName()))
{
serverReg.lista_file_server[j]=lista_file2;
break;
}
}
}//synchro
//aggiorno il
coordinatore
new Thread(new
aggiornaCoordinatore(nome_coordinatore,lista_file2)).start();
}
catch(Exception e)
{
//System.out.println(e);
System.out.println("Errore durante
STOR");
}
}
catch(Exception e)
{
System.out.println("Errore nel
trasferimento del file.");
//System.out.println(e);
comandiOut.println("452 Request
action not taken.");
}
}
//COMANDO APPE: esegue l' append sul file del
server se esiste, altrimenti lo crea
if(messaggio.startsWith("APPE"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO ABOR: interruzione o fine del
trasferimento di dati, chiusura porta dati
if(messaggio.startsWith("ABOR"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented. ");
}
//**********************************************************/
//GRUPPO DI COMANDI PER LA GESTIONE DEI FILE E
DEI DIRETTORI
//**********************************************************/
//COMANDO DELE: cancella un file
if(messaggio.startsWith("DELE"))
{
String
temp_lista2[]=new String[60];
messaggio=messaggio.substring(4);
messaggio=messaggio.trim();
try
{
File
f=new
File(workingPath,messaggio);
if(f.exists())
{
if(f.delete())
{
System.out.println("File "+messaggio+" cancellato
dall\' utente "+nome_utente);
scrittoreLog.write("File "+messaggio+" cancellato
dall\' utente "+nome_utente+"\r\n");
comandiOut.println("250 Sussection:
file deleted.");
temp_lista2=workingPath.list();
for(int i=0;i<temp_lista2.length;i++)
{
if(temp_lista2[i]==null)break;
lista_file[i]=temp_lista2[i];
}
//aggiorno la lista in
locale
synchronized(serverReg)
{
for(int j=0;j<serverReg.lista_server.length;j++)
{
if(serverReg.lista_server[j]==null)break;
if(serverReg.lista_server[j].equals(connessione.getLocalAddress().getHostName()))
{
serverReg.lista_file_server[j]=lista_file;
break;
}
}
}//synchro
//aggiorno il
coordinatore
new Thread(new
aggiornaCoordinatore(nome_coordinatore,lista_file)).start();
}
else
{
System.out.println("Impossibile
cancellare il file "+messaggio+" richiesto dall\' utente "+nome_utente);
scrittoreLog.write("Impossibile
cancellare il file "+messaggio+" richiesto dall\' utente "+nome_utente+"\r\n");
comandiOut.println("550 File
unavailable or remote.");
}
}
else
{
comandiOut.println("550 File
unavailable or remote.");
}
}
catch(NullPointerException
e)
{
System.out.println("L\' utente
"+nome_utente+" non ha
inserito il nome del file");
comandiOut.println("501 Syntax
error in parameters or arguments.");
}
}
//COMANDO LIST: visualizza il contenuto della
directory
if(messaggio.startsWith("LIST")||messaggio.startsWith("NLST"))
{
try
{
Socket
list_sock=new
Socket(connessione.getInetAddress(),remote_port,connessione.getLocalAddress(),porta_FTP_DTP);
comandiOut.println("150 ASCII
data");
scrittoreLog.write("L\' utente
"+nome_utente+": richiesta
lista dei file della directory "+workingPath+"\r\n");
System.out.println("L\' utente
"+nome_utente+": richiesta
lista dei file della directory "+workingPath);
PrintWriter
list_out=new
PrintWriter(list_sock.getOutputStream(),true);
//list_out.println("Contents
of "+workingPath);
list_out.println("Files
available:");
lista_file=workingPath.list();
//lista file locali e
remoti
for(int yy=0;yy<lista_file.length;yy++)
{
if(lista_file[yy]==null)break;
list_out.println("-lc- "+lista_file[yy]);
}
synchronized(serverReg)
{
for(int j=0;j<serverReg.lista_server.length;j++)
{
if(serverReg.lista_server[j]==null)break;
for(int i=0;i<serverReg.lista_file_server[j].length;i++)
{
if(serverReg.lista_file_server[j][i]==null)break;
if(serverReg.lista_server[j].equals(connessione.getLocalAddress().getHostName()))
{
//list_out.println("-lc-
"+serverReg.lista_file_server[j][i]);
}
else
{
list_out.println("-rm- "+serverReg.lista_file_server[j][i]);
}
}
}
}//synchro
//System.out.println("Fine
lista file");
list_out.close();
comandiOut.println("226 Transfer
complete.");
}
catch(Exception e)
{
System.out.println(e);
comandiOut.println("450 Requested
file action not taken.");
}
}
//COMANDO PWD: visualizza la directory
corrente sul server
if(messaggio.startsWith("PWD"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO CDUP: passare alla directory
superiore
if(messaggio.startsWith("CDUP"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO CWD: cambiare la directory corrente
if(messaggio.startsWith("CWD"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO RNFR: cambia il nome del file da ...
(viene seguito da RNTO)
if(messaggio.startsWith("RNFR"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO RNTO: cambia il nome del file in ...
if(messaggio.startsWith("RNTO"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO RMD: rimuove la directory
specificata
if(messaggio.startsWith("RMD"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
//COMANDO MKD: crea la directory specificata
if(messaggio.startsWith("MKD"))
{
//Gestire il comando
comandiOut.println("502 command not
implemented.");
}
}
//CHIUSURA DELLA CONNESSIONE
comandiOut.println("221
Arrivederci! Comunicazione terminata.\r\n");
scrittoreLog.write(client_remoto+": invio
messaggio di chiusura\r\n");
scrittoreLog.flush();
connessione.close();
scrittoreLog.close();
System.out.println("Connessione
chiusa con "+client_remoto);
}
catch(IOException e)
{System.err.println(e);}
}
public void registraUtenti()
{
try
{
FileOutputStream out = new FileOutputStream("iscritti.dat",false);
ObjectOutputStream oos = new
ObjectOutputStream(out);
try
{
oos.writeObject(new Iscritto("simone","simone"));
oos.writeObject(new Iscritto("anonimo","ftp"));
oos.writeObject(new Iscritto("psimon","psimon"));
oos.flush();
oos.close();
out.close();
}
catch(IOException e)
{
System.err.println(e);
}
}
catch(Exception e)
{
}
}
public boolean leggi(Iscritto iscr)
{
boolean trovato=false;
try
{
FileInputStream in = new FileInputStream("iscritti.dat");
ObjectInputStream ois = new ObjectInputStream(in);
try
{
while(true)
{
Iscritto i = (Iscritto) ois.readObject();
if(i.equals(iscr)) {trovato=true;break;}
}
ois.close();
in.close();
}
catch(IOException ee)
{
if(!ee.getClass().toString().equals("class java.io.EOFException"))
{
System.out.println(ee);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
catch(Exception e)
{
}
return trovato;
}
}