/* ** This file is part of Filius, a network construction and simulation software. ** ** Originally created at the University of Siegen, Institute "Didactics of ** Informatics and E-Learning" by a students' project group: ** members (2006-2007): ** André Asschoff, Johannes Bade, Carsten Dittich, Thomas Gerding, ** Nadja Haßler, Ernst Johannes Klebert, Michell Weyer ** supervisors: ** Stefan Freischlad (maintainer until 2009), Peer Stechert ** Project is maintained since 2010 by Christian Eibl <filius@c.fameibl.de> ** and Stefan Freischlad ** Filius is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 2 of the License, or ** (at your option) version 3. ** ** Filius is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ** PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with Filius. If not, see <http://www.gnu.org/licenses/>. */ package filius.software.email; import java.util.LinkedList; import java.util.ListIterator; import filius.Main; import filius.rahmenprogramm.EingabenUeberpruefung; import filius.rahmenprogramm.I18n; import filius.software.clientserver.ClientAnwendung; import filius.software.transportschicht.TCPSocket; public class POP3Client extends ClientAnwendung implements I18n { private EmailAnwendung anwendung; public POP3Client(EmailAnwendung anwendung) { super(); Main.debug.println("INVOKED-2 ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), constr: POP3Client("+anwendung+")"); this.anwendung = anwendung; this.setSystemSoftware(anwendung.getSystemSoftware()); } /** * Diese Methode startet die blockierenden Methoden zum E-Mail-Abruf in dem * Thread der Anwendung. Deshalb ist der Aufruf dieser Methode <b> nicht * blockierend </b>! * * @param pop3Server * @param pop3Port * @param benName * @param pw */ public void emailsHolen(String pop3Server, String pop3Port, String benName, String pw) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), emailsHolen("+pop3Server+","+pop3Port+","+benName+","+pw+")"); Object[] args; args = new Object[2]; args[0] = pop3Server; args[1] = new Integer(pop3Port); ausfuehren("initialisiereSocket", args); args = new Object[2]; args[0] = benName; args[1] = pw; ausfuehren("starteVerarbeitung", args); ausfuehren("schliesseSocket", null); } /** * Hier wird ein neuer Socket erzeugt und verbunden * * @param zielAdresse * @param port */ public void initialisiereSocket(String zielAdresse, Integer port) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), initialisiereSocket("+zielAdresse+","+port+")"); try { socket = new TCPSocket(getSystemSoftware(), zielAdresse, port); socket.verbinden(); } catch (Exception e) { e.printStackTrace(Main.debug); socket = null; anwendung.benachrichtigeBeobachter(e); } } /** * Hier wird das Schema runtergebetet, nach dem Emails vom POP3Server * abgeholt werden - benutzerauthentifizierung * benutzername * passwort - * status der Mailbox - emails auflisten - email abrufen * * @return boolean */ public void starteVerarbeitung(String benName, String pw) { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), starteVerarbeitung("+benName+","+pw+")"); boolean erfolg = true; if (socket != null && socket.istVerbunden()) { try { erfolg = socket.empfangen().startsWith("+"); if (erfolg) erfolg = eingabeBenutzername(benName); if (erfolg) erfolg = eingabePasswort(pw); if (erfolg) erfolg = alleEmailsAbrufen(); sitzungBeenden(); } catch (Exception e) { e.printStackTrace(Main.debug); anwendung.benachrichtigeBeobachter(e); } anwendung.benachrichtigeBeobachter(); } } private boolean alleEmailsAbrufen() throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), alleEmailsAbrufen()"); String[] statusteile; int anzahlMails = 0; String auflistung = ""; LinkedList<Integer> emailIDs = new LinkedList<Integer>(); statusteile = statusAbrufen().split(" "); if (statusteile.length > 0) { anzahlMails = Integer.parseInt(statusteile[0]); } if (anzahlMails > 0) { // Auflistung aller Emails (Mit Nummer (Leerzeichen) Gre in Bytes) auflistung = emailsAuflisten(); // nach jeder Email wird getrennt String[] zeilen = auflistung.split("\n"); // es wird bei 1 angefangen um das "+OK" zu Beginn der Übertragung // auszusparen for (int i = 1; i < zeilen.length; i++) { String zeile = zeilen[i]; String[] zeichen = zeile.split(" "); emailIDs.add(Integer.parseInt(zeichen[0])); // es wird immer der // Index zur Liste // hinzugefügt } } /* * Aus dem String aus emailsAuflisten wird eine LinkedList der Email-IDs * erzeugt. Diese wird iteriert und RETR fr jede Mail aufgerufen. Die * Emails werden als String geliefert */ ListIterator iter = emailIDs.listIterator(); while (iter.hasNext()) { int id = (Integer) iter.next(); emailAbrufen(id); emailLoeschen(id); } return true; } /** * Diese Methode ist <b>blockierend</b>. * */ public void schliesseSocket() { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), schliesseSocket()"); if (socket != null) { socket.schliessen(); socket = null; benachrichtigeBeobachter(messages.getString("sw_pop3client_msg1")); } } /** * FUNKTIONIERT * * @param benutzername * @throws Exception */ private boolean eingabeBenutzername(String benutzername) throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), eingabeBenutzername("+benutzername+")"); if (EingabenUeberpruefung.isGueltig(benutzername, EingabenUeberpruefung.musterMindEinZeichen)) { socket.senden("USER " + benutzername); String empfangen = socket.empfangen(); if (empfangen.startsWith("+OK")) return true; else throw new Exception(empfangen); } else { return false; } } /** * FUNKTIONIERT * * @param passwort * @throws Exception */ private boolean eingabePasswort(String passwort) throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), eingabePasswort("+passwort+")"); if (EingabenUeberpruefung.isGueltig(passwort, EingabenUeberpruefung.musterMindEinZeichen)) { socket.senden("PASS " + passwort); String z = socket.empfangen(); if (z.startsWith("+OK")) return true; else throw new Exception(z); } else { return false; } } /** * FUNKTIONIERT Hiermit wird der Status der Mailbox abgefragt. Es wird der * Befehl pop3-maessig (STAT) an den POP3Server gesendet. * * @throws Exception * */ private String statusAbrufen() throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), statusAbrufen()"); String antwort, ergebnis; String[] temp; socket.senden("STAT"); antwort = socket.empfangen(); if (antwort.startsWith("+OK")) { temp = antwort.split(" "); ergebnis = temp[1] + " " + temp[2]; return ergebnis; } else { throw new Exception(antwort); } } /** * FUNKTIONIERT Hier wird der Befehl LIST gesendet, einmal ohne Attribut, * wenn alle emails aufgelistet werden sollen, und einmal mit, wenn nur die * Email mit dem Index i aufgelistet werden soll. * * @param i * @throws Exception */ private boolean emailsAuflisten(int i) throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), emailsAuflisten("+i+")"); String ergebnis; socket.senden("LIST " + i); ergebnis = socket.empfangen(); if (ergebnis.startsWith("+OK")) return true; else throw new Exception(ergebnis); } /** * In dieser Methode werden alle Emails aufgelistet. * * @return String * @throws Exception */ private String emailsAuflisten() throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), emailsAuflisten()"); String ergebnis; socket.senden("LIST"); ergebnis = socket.empfangen(); if (ergebnis.startsWith("+OK")) return ergebnis; else throw new Exception(ergebnis); } /** * FUNKTIONIERT ruft eine email vom Server ab. Es wird die Email mit dem als * Attribut uebergebenen Index abgerufen. * * @param i * @throws Exception */ private void emailAbrufen(int i) throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), emailsAbrufen("+i+")"); int pos; Email neMail; socket.senden("RETR " + i); String result = socket.empfangen(); if (result.startsWith("+OK")) { // hier wird das Email-Objekt dem Nachrichtenkonto hinzugefuegt pos = result.indexOf("\n"); if (pos > 0) { neMail = new Email(result.substring(pos + 1)); anwendung.getEmpfangeneNachrichten().add(neMail); } } else { throw new Exception(result); } } /** * FUNKTIONIERT UEBERARBEITEN DENNOCH 2008 Hier wird der Befehl zum * loeschen, d.h. eine Email als zu loeschen nach dem Ende der Sitzung * markiert, gesendet. * * @param i * @throws Exception */ private boolean emailLoeschen(int i) throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), emailLoeschen("+i+")"); String ergebnis; socket.senden("DELE " + i); ergebnis = socket.empfangen(); if (ergebnis.startsWith("+OK")) return true; else throw new Exception(ergebnis); } /** * UEBERARBEITEN Hiermit wird die Sitzung beendet. Das heißt auch, dass der * eigene Thread, die Kommunikation beendet werden muss. * * @throws Exception * */ private boolean sitzungBeenden() throws Exception { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), sitzungBeenden()"); String ergebnis; socket.senden("QUIT"); ergebnis = socket.empfangen(); if (ergebnis.startsWith("+OK")) return true; else throw new Exception(ergebnis); } /** * FUNKTIONIERT Diese Methode provoziert lediglich einen response vom * Server... * */ private String noop() { Main.debug.println("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (POP3Client), noop()"); String ergebnis = ""; try { socket.senden("NOOP"); ergebnis = socket.empfangen(); } catch (Exception e) { e.printStackTrace(Main.debug); ergebnis = "-ERR NOOP failure in Email-Client"; } return ergebnis; } }