Se qualcuno intende fornire approcci diversi/migliori o segnalare problemi sintattico-logici è ben accetto.
*************************
Imports - sono stati fatti col ctrl+o di eclipse, quindi magari c'è qualcosa di troppo, di preciso non so a dire il vero.
Codice: Seleziona tutto
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
Main -> compito del main sarà solamente quello di sequenzializzare i filtri che progressivamente si occuperanno di pulire l'input stream e quello
di settare il threeshold level per la stampa a schermo [o eventualmente su file] dell'output. A breve pensavo di impotarlo come argomento da linea di comando di modo da poter scegliere se andare a file o a schermo. Ad ogni modo per il momento ho "appoggiato" tutto su di un batchetto ">".
Codice: Seleziona tutto
public class MyIParser {
static String _path = "PATH";
public static void main(String[] args) {
File path = new File(_path);
File [] lista = path.listFiles();
int AlarmLevel = 0;
if(args.length < 1) AlarmLevel = 3;
else AlarmLevel = Integer.parseInt(args[0]);
int fileNum = lista.length;
System.out.println(fileNum + " email di spam");
LinkedList<String> stageone = ipChecker(lista);
LinkedList<String> stagetwo = StringCleaner(stageone);
LinkedList<String> cleanOne = ListCleaner(stagetwo)
LinkedList<Couple> result = OccurrenceCalculator(stagetwo, cleanOne);
for(Couple l: result)
{
if(l.counter > AlarmLevel) System.out.println(l);
}
}
Prende come input la lista dei file presenti nella cartella "PATH". Per ognuno di essi estrae unicamente la prima riga contenentente le parole
"Received: from" [che, salvo headers aggiunti a mano/script, contiene l'ip dell'ultimo host attraversato] e la da in pasto allo script successivo.
Codice: Seleziona tutto
public static LinkedList<String> ipChecker(File[] lista)
{
LinkedList<String> stageone = new LinkedList<String>();
for (int i=0; i<lista.length; i++) {
if ( !lista[i].isDirectory() ) {
try {
File m = lista[i];
String filename = m.getAbsolutePath();
BufferedReader in = new BufferedReader(new FileReader(filename));
String str;
boolean checker = false;
while ((str = in.readLine()) != null) {
if(checker == false)
{
if (str.contains("Received: from"))
{
stageone.add(str);
checker = true;
}
}
else
{
break;
}
}
in.close();
}
catch (IOException e) {}
}
}
return stageone;
}
Da ogni stringa che gli viene passata attraverso la lista stageone, estrae gli ip che sono contenuti tra parentesi quadre. Se ci fossi riuscito avrei utilizzato una regex. Purtroppo pero' nonostante diversi tentativi ho sempre ottenuto "FALSE" in risposta, e quindi ho approfittato della particolare formattazione dei file EML ai fini di un algoritmo maggiormente primitivo e meno "generico".
Codice: Seleziona tutto
public static LinkedList<String> StringCleaner(LinkedList<String> stageone)
{
Iterator it = stageone.iterator();
LinkedList<String> stagetwo = new LinkedList<String>();
while(it.hasNext())
{
String t = (String)it.next();
int start = t.indexOf("[");
int stop = t.indexOf("]");
String subst = t.substring(start+1, stop);
stagetwo.add(subst);
}
return stagetwo;
}
Prende in input la lista contenente (presumibilmente) tutti gli ip da cui sono partite email di spam. Dopo averla ordinata crea una nuova lista dove vengono copiate le voci univoche.
Codice: Seleziona tutto
public static LinkedList<String> ListCleaner(LinkedList<String> stagetwo)
{
Collections.sort(stagetwo);
LinkedList<String> ListaPulita = new LinkedList<String>();
Iterator it = stagetwo.iterator();
while(it.hasNext())
{
String temp = (String)it.next();
if(!(ListaPulita.contains(temp)))
{
ListaPulita.add(temp);
}
}
return ListaPulita;
}
"sporca" [StageTwo] dopodichè, dopo aver piazzato il risultato in una <Couple> [Semplice classe composta da un attributo string e uno int, che
conterranno rispettivamente l'ip e quante volte è stato individuato] la associa come elemento al resultset, che verrà poi restituito al main per
essere stampato.
Codice: Seleziona tutto
public static LinkedList<Couple> OccurrenceCalculator(LinkedList<String> stagetwo, LinkedList<String> cleanOne)
{
LinkedList<Couple> resultset = new LinkedList<Couple>();
Iterator itClean = cleanOne.iterator();
Iterator itStage = stagetwo.iterator();
int counter = 0;
while(itClean.hasNext())
{
counter = 0;
String temp = (String)itClean.next();
while(stagetwo.contains(temp))
{
counter++;
stagetwo.removeLastOccurrence(temp);
}
resultset.add(new Couple(temp, counter));
}
return resultset;
}
PS: avrei tendenzialmente usato altro, qualcosa di più "low level", ma essendo java il linguaggio in cui mi muovo meglio...