better listener detection/dispatch
[org.ibex.jinetd.git] / src / org / ibex / jinetd / Port.java
index 470c0a0..8ac02a5 100644 (file)
@@ -33,7 +33,16 @@ public class Port extends Loader {
         super.changed(w);
     }
 
-    boolean dispatch(final Connection conn) throws Exception {
+
+    Class isListener(String name) throws ClassNotFoundException {
+        final ClassLoader cl = getClassLoader();
+        final Class c = cl.loadClass(name);
+        if (c == null) return null;
+        if (Listener.class.isAssignableFrom(c) && c != Listener.class) return c;
+        return null;
+    }
+
+    Class findListener() throws Exception {
         getClassLoader();
         String[] list = list();
         for(int i=0; i<list.length; i++) {
@@ -46,55 +55,55 @@ public class Port extends Loader {
                 ZipInputStream zis = new ZipInputStream(fis);
                 for(ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
                     String name = ze.getName();
-                    if (name.endsWith(".class"))
-                        if (dispatch(conn, name.substring(0, name.length() - ".class".length()).replace('/', '.')))
-                            return true;
+                    if (name.endsWith(".class")) {
+                        String classname = name.substring(0, name.length() - ".class".length()).replace('/', '.');
+                        Class c = isListener(classname);
+                        if (c != null) return c;
+                    }
                 }
             } finally { if (fis != null) fis.close(); }
         }
-        if (check(conn, new File(getAbsolutePath() + File.separatorChar + "BIN"))) return true;
-        return false;
+        return findListener(new File(getAbsolutePath() + File.separatorChar + "BIN"));
     }
 
-    boolean check(Connection conn, File f) throws Exception {
-        if (!f.exists()) return false;
+    Class findListener(File f) throws Exception {
+        if (!f.exists()) return null;
         if (!f.isDirectory()) {
-            if (!f.getAbsolutePath().endsWith(".class")) return false;
+            if (!f.getAbsolutePath().endsWith(".class")) return null;
             String name = f.getAbsolutePath().substring(getAbsolutePath().length() + 5);
             name = name.substring(0, name.length() - ".class".length()).replace(File.separatorChar, '.');
-            if (dispatch(conn, name)) return true;
+            Class c = isListener(name);
+            if (c != null) return c;
         } else {
             String[] list = f.list();
-            for(int i=0; i<list.length; i++) 
-                if (check(conn, new File(f.getAbsolutePath() + File.separatorChar + list[i])))
-                    return true;
+            for(int i=0; i<list.length; i++) {
+                String classname = f.getAbsolutePath() + File.separatorChar + list[i];
+                Class c = findListener(new File(classname));
+                if (c != null) return c;
+            }
         }
-        return false;
+        return null;
     }
 
-    boolean dispatch(final Connection conn, String name) throws Exception {
-        try {
-            final ClassLoader cl = getClassLoader();
-            final Class c = cl.loadClass(name);
-            if (c == null) return false;
-            if (!(Listener.class.isAssignableFrom(c) && c != Listener.class)) return false;
-            Log.info(this, "dispatching connection on port " + port + " to " + c.getName());
-            new Thread(tg, new Runnable() { public void run() {
+    void dispatch(final Connection conn) throws Exception {
+        new Thread(tg, new Runnable() { public void run() {
+            try {
+                Class c = findListener();
+                if (c == null) throw new RuntimeException("couldn't find listener");
+                Log.info(this, "dispatching connection on port " + port + " to " + c.getName());
                 Log.clearnotes();
+                final ClassLoader cl = getClassLoader();
                 Thread.currentThread().setContextClassLoader(cl);
-                try {
-                    Listener l = (Listener)c.newInstance();
-                    l.accept(conn);
-                } catch (Exception e) {
-                    Log.error(c, "Listener threw exception");
-                    Log.error(c, e);
-                } finally {
-                    conn.close();
-                }
-            } }).start();
-            return true;
-        } catch (Exception e) { Log.error(this, e); }
-        return false;
+                Listener l = (Listener)c.newInstance();
+                l.accept(conn);
+            } catch (Exception e) {
+                Log.error(this, "Listener threw exception");
+                Log.error(this, e);
+                conn.close();
+            } finally {
+                conn.close();
+            }
+        } }).start();
     }
 
     private class PortThread extends Thread {
@@ -107,10 +116,7 @@ public class Port extends Loader {
                          ", port " + port);
                 ServerSocket ss = bindTo == null ? new ServerSocket(port) : new ServerSocket(port, 0, bindTo);
                 for(Socket s = ss.accept(); ; s = ss.accept()) try {
-                    if (!dispatch(new Connection(s, "megacz.com"))) {
-                        Log.warn(this, "no handler for connection on port " + port);
-                        s.close();
-                    }
+                    dispatch(new Connection(s, "megacz.com"));
                 } catch (Exception e) { Log.warn(Port.class, e); }
             } catch (Exception e) { Log.error(Port.class, e);
             } catch (Throwable t) {