/* ** 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.lokal; import java.util.Calendar; import java.util.Enumeration; import java.util.LinkedList; import java.util.ListIterator; import javax.swing.tree.DefaultMutableTreeNode; import filius.Main; import filius.exception.SocketException; import filius.rahmenprogramm.I18n; import filius.software.clientserver.ClientAnwendung; import filius.software.system.Betriebssystem; import filius.software.system.Datei; import filius.software.system.Dateisystem; import filius.software.system.InternetKnotenBetriebssystem; import filius.software.transportschicht.ServerSocket; import filius.software.transportschicht.Socket; import filius.software.transportschicht.SocketSchnittstelle; import filius.software.transportschicht.TransportProtokoll; import filius.software.vermittlungsschicht.IP; import filius.software.vermittlungsschicht.IcmpPaket; /** * Diese Klasse soll eine Art Eingabeaufforderung oder Unix-Shell darstellen, * in der zumindest rudimentaere Befehle wie dir/ls/rename etc. moeglich sein sollen. * Auerdem soll hierin auch der Start von bestimmten Serveranwendungen und netcat moeglich * sein. * * @author Thomas Gerding & Johannes Bade * */ public class Terminal extends ClientAnwendung implements I18n { //Betriebssystem betriebssystem; boolean abfrageVar; private DefaultMutableTreeNode aktuellerOrdner; private boolean interrupted = false; public void setSystemSoftware(InternetKnotenBetriebssystem bs) { super.setSystemSoftware(bs); this.aktuellerOrdner = getSystemSoftware().getDateisystem().getRoot(); } /** * Diese Funktion bildet "move" bzw. "rename" ab und erlaubt es eine bestimmte * Datei umzubenennen. * * @param alterName Der bisherige Dateiname * @param neuerName Der gewnschte neue Dateiname * @return Gibt eine Meldung ueber den Erfolg oder Misserfolg des Umbenennens zurck. * @author Thomas Gerding & Johannes Bade */ public String move(String [] args) { return mv(args); } public String mv(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (Terminal), mv("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,2)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg40")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg40"); // wrong number of parameters } if(pureCopy(args)) { // positive case, everything worked fine this.getSystemSoftware().getDateisystem().deleteFile(filius.software.system.Dateisystem.absoluterPfad(getAktuellerOrdner())+Dateisystem.FILE_SEPARATOR+args[0]); benachrichtigeBeobachter(messages.getString("sw_terminal_msg35")); return messages.getString("sw_terminal_msg35"); } else { benachrichtigeBeobachter(messages.getString("sw_terminal_msg36")); return messages.getString("sw_terminal_msg36"); } // negative case, something wrong } /** * delete file */ public String rm(String[] args) { return del(args); } public String del(String[] args) { Main.debug.print("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (Terminal), del("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg41")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg41"); // wrong number of parameters } if (this.getSystemSoftware().getDateisystem().deleteFile(filius.software.system.Dateisystem.absoluterPfad(getAktuellerOrdner())+Dateisystem.FILE_SEPARATOR+args[0])) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg37")); return messages.getString("sw_terminal_msg37"); } else { benachrichtigeBeobachter(messages.getString("sw_terminal_msg38")); return messages.getString("sw_terminal_msg38"); } } /** * Kopiert eine Datei * * @param Parameter Array (String) * @return */ //// common functionality for move and copy... private boolean pureCopy(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (Terminal), pureCopy("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); this.getSystemSoftware().getDateisystem().printTree(); String srcString = args[0]; if(srcString.length()>0 && srcString.substring(0,1).equals(Dateisystem.FILE_SEPARATOR)) { // 'pfad' is absolute path! srcString = Dateisystem.evaluatePathString(srcString); } else { srcString = Dateisystem.evaluatePathString(filius.software.system.Dateisystem.absoluterPfad(getAktuellerOrdner())+Dateisystem.FILE_SEPARATOR+srcString); } String destString = args[1]; if(destString.length()>0 && destString.substring(0,1).equals(Dateisystem.FILE_SEPARATOR)) { // 'pfad' is absolute path! destString = Dateisystem.evaluatePathString(destString); } else { destString = Dateisystem.evaluatePathString(filius.software.system.Dateisystem.absoluterPfad(getAktuellerOrdner())+Dateisystem.FILE_SEPARATOR+destString); } String destDir = Dateisystem.getDirectory(destString); String destFile = Dateisystem.getBasename(destString); //Main.debug.println("DEBUG: pureCopy: source '"+srcDir+"'-'"+srcFile+"', destination '"+destDir+"'-'"+destFile+"'"); Datei sfile = this.getSystemSoftware().getDateisystem().holeDatei(srcString); if (sfile == null) return false; Datei dfile = new Datei(destFile,sfile.getDateiTyp(),sfile.getDateiInhalt()); return this.getSystemSoftware().getDateisystem().speicherDatei(destDir, dfile); } // individual functionality for copy only public String copy(String [] args) { return cp(args); } public String cp(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", T"+this.getId()+") "+getClass()+" (Terminal), cp("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,2)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg40")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg40"); // wrong number of parameters } if(pureCopy(args)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg33")); return messages.getString("sw_terminal_msg33"); } // positive case, everything worked fine else { benachrichtigeBeobachter(messages.getString("sw_terminal_msg34")); return messages.getString("sw_terminal_msg34"); } // negative case, something wrong } /* */ public String ipconfig(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), ipconfig("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,0)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg42")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg42"); // wrong number of parameters } Betriebssystem bs = (Betriebssystem) getSystemSoftware(); String ausgabe = ""; ausgabe += messages.getString("sw_terminal_msg4") + " " + bs.holeIPAdresse() + "\n"; ausgabe += messages.getString("sw_terminal_msg5") + " " + bs.holeNetzmaske() + "\n"; ausgabe += messages.getString("sw_terminal_msg26") + " " + bs.holeMACAdresse() + "\n"; ausgabe += messages.getString("sw_terminal_msg6") + " " + bs.getStandardGateway() + "\n"; ausgabe += messages.getString("sw_terminal_msg27") + " " + bs.getDNSServer() + "\n"; benachrichtigeBeobachter(ausgabe); return ausgabe; } /* Entspricht route print unter windows */ public String route(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), route("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,0)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg42")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg42"); // wrong number of parameters } String ausgabe = messages.getString("sw_terminal_msg7"); LinkedList<String[]> routingTabelle = getSystemSoftware().getWeiterleitungstabelle().holeTabelle(); ListIterator<String[]> it = routingTabelle.listIterator(); while (it.hasNext()) { String[] eintrag = (String[])it.next(); ausgabe+="| "; for (int i=0;i<eintrag.length;i++) { ausgabe += eintrag[i] + stringFuellen(15-eintrag[i].length(), " ") + " | "; } ausgabe+="\n"; } benachrichtigeBeobachter(ausgabe); return ausgabe; } /** * Diese Funktion bietet Aehnliches wie "ls" oder "dir" auf der normalen Eingabeaufforderung. * Es gibt eine Liste aller Dateien des Rechners und deren Groesse zurueck. * * @return Gibt die Liste der vorhandenen Dateien (und Verzeichnisse) in * einem formatierten String zurueck, der direkt ausgegeben * werden kann. * * @author Thomas Gerding & Johannes Bade * @param Parameter Array (String) */ public String ls(String [] args) { return dir(args); } public String dir(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), dir("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,0,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg43")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg43"); // wrong number of parameters } LinkedList<Object> liste; StringBuffer inhalt; String currPath; int anzahlVerzeichnisse = 0; int anzahlDateien = 0; Datei tmpDatei; int leerzeichen; if(args[0].isEmpty()) { liste = getSystemSoftware().getDateisystem().listeVerzeichnis(aktuellerOrdner); currPath = Dateisystem.absoluterPfad(aktuellerOrdner); } else { if(args[0].length()>0 && args[0].substring(0,1).equals(Dateisystem.FILE_SEPARATOR)) { // argument given as absolute path! liste = getSystemSoftware().getDateisystem().listeVerzeichnis(getSystemSoftware().getDateisystem().verzeichnisKnoten(args[0])); currPath = Dateisystem.evaluatePathString(args[0]); } else { liste = getSystemSoftware().getDateisystem().listeVerzeichnis(Dateisystem.verzeichnisKnoten(aktuellerOrdner,args[0])); currPath = Dateisystem.evaluatePathString(Dateisystem.absoluterPfad(aktuellerOrdner) + Dateisystem.FILE_SEPARATOR + args[0]); } } if (liste == null || liste.size() == 0) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg8")); return messages.getString("sw_terminal_msg8"); } else { inhalt = new StringBuffer(); inhalt.append(messages.getString("sw_terminal_msg9") + " " + currPath + ":\n"); for (Object tmp : liste) { // Fall Datei: if (tmp instanceof Datei) { anzahlDateien++; tmpDatei = (Datei) tmp; leerzeichen = 40 - tmpDatei.getName().length(); inhalt.append(tmpDatei.getName()+ stringFuellen(leerzeichen, ".") + tmpDatei.holeGroesse() + "\n"); } // Fall Ordner: else { anzahlVerzeichnisse++; inhalt.append("[" + tmp + "]\n"); } } inhalt.append(messages.getString("sw_terminal_msg10") + anzahlVerzeichnisse); inhalt.append(messages.getString("sw_terminal_msg11") + anzahlDateien + "\n"); } benachrichtigeBeobachter(inhalt.toString()); return inhalt.toString(); } /** * * touch * */ public String touch(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), touch("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg41")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg41"); // wrong number of parameters } String ergebnis = messages.getString("sw_terminal_msg12"); String absPath; if(args[0].length()>0 && args[0].substring(0,1).equals(Dateisystem.FILE_SEPARATOR)) { // 'pfad' is absolute path! absPath = Dateisystem.evaluatePathString(args[0]); } else { absPath = Dateisystem.evaluatePathString(Dateisystem.absoluterPfad(aktuellerOrdner)+Dateisystem.FILE_SEPARATOR+args[0]); } String filePath = Dateisystem.getDirectory(absPath); String dateiName = Dateisystem.getBasename(absPath); if (!dateiName.equals("")) { if (!getSystemSoftware().getDateisystem().dateiVorhanden(filePath, dateiName)) { getSystemSoftware().getDateisystem().speicherDatei(filePath, new Datei(dateiName,"text/txt","")); ergebnis = messages.getString("sw_terminal_msg13"); } else { ergebnis = messages.getString("sw_terminal_msg14"); } } else { ergebnis = messages.getString("sw_terminal_msg15"); } benachrichtigeBeobachter(ergebnis); return ergebnis; } /** * * mkdir * */ public String mkdir(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), mkdir("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg41")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg41"); // wrong number of parameters } String ergebnis = messages.getString("sw_terminal_msg16"); String absPath; if(args[0].length()>0 && args[0].substring(0,1).equals(Dateisystem.FILE_SEPARATOR)) { // 'pfad' is absolute path! absPath = Dateisystem.evaluatePathString(args[0]); } else { absPath = Dateisystem.evaluatePathString(Dateisystem.absoluterPfad(aktuellerOrdner)+Dateisystem.FILE_SEPARATOR+args[0]); } String filePath = Dateisystem.getDirectory(absPath); String dateiName = Dateisystem.getBasename(absPath); if (!dateiName.equals("")) { if (!getSystemSoftware().getDateisystem().dateiVorhanden(filePath, dateiName) && getSystemSoftware().getDateisystem().erstelleVerzeichnis(filePath, dateiName)) { ergebnis = messages.getString("sw_terminal_msg17"); } else { ergebnis = messages.getString("sw_terminal_msg18"); } } else { ergebnis = messages.getString("sw_terminal_msg19"); } benachrichtigeBeobachter(ergebnis); return ergebnis; } /** * * cd * */ public String cd(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), cd("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); String ergebnis = ""; if(!numParams(args,0,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg43")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg43"); // wrong number of parameters } if (numParams(args,1)) { DefaultMutableTreeNode newDir; if(args[0].charAt(0) == '/') // absolute path newDir = getSystemSoftware().getDateisystem().changeDirectory(args[0]); else // relative path newDir = getSystemSoftware().getDateisystem().changeDirectory(Dateisystem.absoluterPfad(aktuellerOrdner),args[0]); if(newDir != null) { // first, check whether directory change was successful; otherwise stay in current directory aktuellerOrdner = newDir; } else { ergebnis = messages.getString("sw_terminal_msg20"); } } else { ergebnis=Dateisystem.absoluterPfad(aktuellerOrdner); } benachrichtigeBeobachter(ergebnis); return ergebnis; } // Unix Tool 'pwd': print working directory public String pwd(String[] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), pwd("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,0)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg42")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg42"); // wrong number of parameters } String ergebnis=Dateisystem.absoluterPfad(aktuellerOrdner); benachrichtigeBeobachter(ergebnis); return ergebnis; } public String netstat(String[] args) { TransportProtokoll transport; StringBuffer ergebnis = new StringBuffer(); String protocol; ergebnis.append(messages.getString("sw_terminal_msg49")); ergebnis.append("--------------------------------------------------------------------------\n"); transport = this.getSystemSoftware().holeTcp(); protocol = "TCP"; this.processTransportProtocol(ergebnis, transport, protocol); transport = this.getSystemSoftware().holeUdp(); protocol = "UDP"; this.processTransportProtocol(ergebnis, transport, protocol); benachrichtigeBeobachter(ergebnis); return ergebnis.toString(); } private void processTransportProtocol(StringBuffer ergebnis, TransportProtokoll transport, String protocol) { Enumeration<Integer> benutztePorts; int port; SocketSchnittstelle tmpSocket; String[] socketData; benutztePorts = transport.holeAktiveSockets().keys(); while (benutztePorts.hasMoreElements()) { port = benutztePorts.nextElement().intValue(); try { tmpSocket = transport.holeSocket(port); socketData = this.getSocketInformation(tmpSocket); ergebnis.append(String.format("| %-8s ", protocol)); ergebnis.append(String.format("| %-6s ", ""+port)); ergebnis.append(String.format("| %-15s ", socketData[0])); ergebnis.append(String.format("| %-15s ", socketData[1])); ergebnis.append(String.format("| %-14s |\n", socketData[2])); } catch (SocketException e) { e.printStackTrace(); } } } private String[] getSocketInformation(SocketSchnittstelle socket) { String[] routingEntry; String localAddress="", remoteAddress="", state=""; if (socket instanceof Socket) { remoteAddress = ((Socket) socket).holeZielIPAdresse(); routingEntry = ((InternetKnotenBetriebssystem)this.getSystemSoftware()).getWeiterleitungstabelle().holeWeiterleitungsZiele(remoteAddress); if (routingEntry != null) { localAddress = routingEntry[1]; } else { localAddress = "<unknown>"; } state = ((Socket)socket).getStateAsString(); } else if (socket instanceof ServerSocket) { remoteAddress = "-"; localAddress = "-"; state = "LISTEN"; } return new String[]{localAddress, remoteAddress, state}; } /** * * test * */ public String test(String [] args) { String ergebnis = messages.getString("sw_terminal_msg23"); if (this.getSystemSoftware().getDateisystem().speicherDatei(args[0], new Datei("test","txt","blaaa"))) { ergebnis = messages.getString("sw_terminal_msg24"); } benachrichtigeBeobachter(ergebnis); return ergebnis; } /** * * help command to list all available commands implemented in this terminal application * */ public String help(String [] args) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg25")); return messages.getString("sw_terminal_msg25"); } /** * * 'host' command to resolve URL to an IP address using the client's DNS server entry * */ public String host(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), host("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg44")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg44"); // wrong number of parameters } Betriebssystem bs = (Betriebssystem) getSystemSoftware(); filius.software.dns.Resolver res = bs.holeDNSClient(); if(res == null) { filius.Main.debug.println("ERROR ("+this.hashCode()+"): Terminal 'host': Resolver is null!"); benachrichtigeBeobachter(messages.getString("sw_terminal_msg30")); return messages.getString("sw_terminal_msg30"); } String result; try { result = res.holeIPAdresse(args[0]); if (result != null) { benachrichtigeBeobachter(args[0]+" "+messages.getString("sw_terminal_msg28")+" "+result+"\n"); return args[0]+" "+messages.getString("sw_terminal_msg28")+" "+result+"\n"; } else { filius.Main.debug.println("ERROR ("+this.hashCode()+"): Terminal 'host': result is null!"); benachrichtigeBeobachter(messages.getString("sw_terminal_msg30")); return messages.getString("sw_terminal_msg30"); } } catch (Exception e) { e.printStackTrace(filius.Main.debug); benachrichtigeBeobachter(messages.getString("sw_terminal_msg29")); return messages.getString("sw_terminal_msg29"); } } /** * * 'ping' command to check connectivity via ICMP echo request/reply * */ public String ping(String [] args) { Main.debug.print("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), ping("); for (int i=0; i<args.length; i++) { Main.debug.print(i+"='"+args[i]+"' "); } Main.debug.println(")"); if(!numParams(args,1)) { benachrichtigeBeobachter(messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg44")); return messages.getString("sw_terminal_msg32")+messages.getString("sw_terminal_msg44"); // wrong number of parameters } filius.software.dns.Resolver res = getSystemSoftware().holeDNSClient(); if(res == null) { filius.Main.debug.println("ERROR ("+this.hashCode()+"): Terminal 'host': Resolver is null!"); benachrichtigeBeobachter(messages.getString("sw_terminal_msg30")); return messages.getString("sw_terminal_msg30"); } // first: resolve host name String destIp; try { destIp = IP.ipCheck(args[0]); if(destIp == null) { // args[0] is not an IP address destIp = res.holeIPAdresse(args[0]); } if (destIp == null) { // args[0] could also not be resolved filius.Main.debug.println("ERROR ("+this.hashCode()+"): Terminal 'host': result is null!"); benachrichtigeBeobachter(messages.getString("sw_terminal_msg30")); return messages.getString("sw_terminal_msg30"); } } catch (Exception e) { e.printStackTrace(filius.Main.debug); benachrichtigeBeobachter(messages.getString("sw_terminal_msg29")); return messages.getString("sw_terminal_msg29"); } // second: send several (=4) ICMP echo requests long timeStart, timeDiff; benachrichtigeBeobachter(new Boolean(true)); // inform about a multiple data transmission to the observer benachrichtigeBeobachter("PING "+args[0]+" ("+destIp+")"); int receivedReplies = 0; int num; for (num=0; !interrupted; num++) { try { timeStart = Calendar.getInstance().getTimeInMillis(); /// CAVE: wahrscheinlich hier Queue nötig und blockieren, bis Ergebnis da ist!!! int resTTL = getSystemSoftware().holeICMP().startSinglePing(destIp, num+1); timeDiff = 1000 // wait 1s between single ping executions - (Calendar.getInstance().getTimeInMillis() - timeStart); // subtract needed time for former ping //Main.debug.println("DEBUG: Terminal, ping (num="+(num+1)+"), resTTL="+resTTL+", delay="+(1000-timeDiff)+", timeDiff="+timeDiff); if(resTTL >= 0) { benachrichtigeBeobachter("\nFrom "+args[0]+" ("+destIp+"): icmp_seq="+(num+1)+" ttl="+resTTL+ " time="+(Calendar.getInstance().getTimeInMillis()-timeStart)+"ms"); receivedReplies++; } if (timeDiff > 0) { try { // Main.debug.println("DEBUG: Terminal wartet für "+timeDiff+"ms"); Thread.sleep(timeDiff); // Main.debug.println("DEBUG: Terminal fertig mit Warten"); } catch (InterruptedException e) {} } } catch (java.util.concurrent.TimeoutException e) { benachrichtigeBeobachter("\nFrom "+args[0]+" ("+destIp+"): icmp_seq="+(num+1)+" -- Timeout!"); } catch (Exception e) { e.printStackTrace(filius.Main.debug); } } benachrichtigeBeobachter(new Boolean(false)); // inform about a multiple data transmission to the observer // print statistics benachrichtigeBeobachter("\n--- "+args[0]+" "+messages.getString("sw_terminal_msg45")+" ---\n" + num+" "+messages.getString("sw_terminal_msg46")+", " + receivedReplies+" "+messages.getString("sw_terminal_msg47")+", " + ((int) Math.round((1-(((double) receivedReplies) / ((double) num)))*100))+"% "+messages.getString("sw_terminal_msg48") + "\n"); return ""; } /** * * 'traceroute' prints the route packets take to the network host * (using ICMP Echo Request and ICMP Time Exceeded) * */ public String traceroute(String [] args) { if (!numParams(args,1)) { benachrichtigeBeobachter("Benutzung: traceroute <ziel-IP>"); return null; } int maxHops = 20; // 1.: Hostnamen auflösen String destIP = IP.ipCheck(args[0]); if (destIP == null) { try { filius.software.dns.Resolver res = getSystemSoftware().holeDNSClient(); if (res == null) { benachrichtigeBeobachter( "Fehler: Du hast keinen DNS-Server eingestellt."); return null; } destIP = res.holeIPAdresse(args[0]); } catch (Exception e) { e.printStackTrace(filius.Main.debug); benachrichtigeBeobachter("Fehler: Irgendwas ist ganz doll kaputt."); return null; } } if (destIP == null) { benachrichtigeBeobachter("Fehler: Hostname konnte nicht aufgeloest werden. Sorry!"); return null; } benachrichtigeBeobachter(new Boolean(true)); benachrichtigeBeobachter("traceroute zu " + args[0] + " (" + destIP + "), " + maxHops + " Spruenge maximal\n\n"); // 2.: Pings senden und gucken, was alles zurueckkommt IcmpPaket recv = null; int seqNr = 42*23; int fehler = 0; int ttl; for (ttl = 1; ttl <= maxHops && !interrupted; ttl++) { benachrichtigeBeobachter(" " + ttl + " "); for (int i = 0; i < 3 && !interrupted; i++) { seqNr++; recv = getSystemSoftware().holeICMP().sendProbe(destIP, ttl, seqNr); if (recv != null && recv.getSeqNr() == seqNr) { fehler = 0; break; } fehler++; benachrichtigeBeobachter("* "); } if (fehler == 0) { benachrichtigeBeobachter(recv.getQuellIp()); if (recv.getIcmpType() != 11) { break; } } else if (fehler > 5) { break; } benachrichtigeBeobachter("\n"); } benachrichtigeBeobachter(new Boolean(false)); if (ttl >= maxHops) { benachrichtigeBeobachter("\n\n" + args[0] + " scheint seeehr weit weg zu sein."); } else if (interrupted) { benachrichtigeBeobachter("\n\noh, ich wurde interrupted :("); } else if (recv != null && recv.getIcmpType() == 3) { switch (recv.getIcmpCode()) { case 0: benachrichtigeBeobachter("\n\nFehler: ICMP Network Unreachable von " + recv.getQuellIp()); break; case 1: benachrichtigeBeobachter("\n\nFehler: ICMP Host Unreachable von " + recv.getQuellIp()); break; default: benachrichtigeBeobachter("\n\nFehler: ICMP Destination Unreachable (code " + recv.getIcmpCode() + ") von " + recv.getQuellIp()); break; } } else if (fehler == 0) { benachrichtigeBeobachter("\n\n" + args[0] + " wurde nach " + ttl + " Spruengen erreicht."); } else { benachrichtigeBeobachter("\n\nZu viele Fehler, ich geb' auf."); } return null; } public void setInterrupt(boolean val) { this.interrupted = val; } public void beenden() { setInterrupt(true); super.beenden(); } public void terminalEingabeAuswerten(String enteredCommand, String[] enteredParameters) { Main.debug.println("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), terminalEingabeAuswerten("+enteredCommand+","+enteredParameters+")"); Object[] args= new Object[1]; args[0]=enteredParameters; try { // test, whether method exists; if not, exception will be evaluated this.getClass().getDeclaredMethod(enteredCommand,enteredParameters.getClass()); // Main.debug.println("DEBUG: Terminal, terminalEingabeAuswerten: \n\tMethode '" // + enteredCommand + "' gefunden."); setInterrupt(false); // man will ja auch wieder was ausführen ausfuehren(enteredCommand, args); } catch (NoSuchMethodException e) { benachrichtigeBeobachter(messages.getString("terminal_msg2")+"\n" + messages.getString("terminal_msg3") + "\n"); } catch (Exception e) { e.printStackTrace(Main.debug); } } public DefaultMutableTreeNode getAktuellerOrdner() { return aktuellerOrdner; } public void setAktuellerOrdner(DefaultMutableTreeNode aktuellerOrdner) { this.aktuellerOrdner = aktuellerOrdner; } public String addSlashes(String sl) { Main.debug.println("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), addSlashes("+sl+")"); String slNeu = ""; String letztesZ = ""+sl.charAt(sl.length()-1); if (!letztesZ.equals("/")){slNeu = sl+"/";} return slNeu; } /** * * @author Hannes Johannes Bade & Thomas Gerding * * fuellt einen String mit Leerzeichen auf (bis zur länge a) * * @param a * @param fueller * @return */ //// welche der beiden Methoden wird denn wirklich verwendet? //// bisher war Implementierung exakt identisch --> Verweis aufeinander eingefügt! private String stringFuellen(int a, String fueller) { Main.debug.println("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), stringFuellen("+a+","+fueller+")"); String tmp = ""; for (int i = 0; i < a; i++) { tmp = tmp + fueller; } return tmp; } public String makeEmptyString(int a, String fueller) { return stringFuellen(a,fueller); } /** * method to check for correct number of parameters */ private int countParams(String[] args) { Main.debug.println("INVOKED ("+this.hashCode()+", "+this.getId()+") "+getClass()+" (Terminal), countParams("+args+")"); int count=0; for (int i=0; i<args.length; i++) { if (!args[i].isEmpty()) { count++; } else return count; // return on first empty entry } return count; } private boolean numParams(String[] args,int exactNum) { return (exactNum==countParams(args)); } private boolean numParams(String[] args,int minNum,int maxNum) { int count=countParams(args); return ((count>=minNum) && (count<=maxNum)); } }