import
[org.ibex.jinetd.git] / src / org / ibex / jinetd / Port.java
1 package org.ibex.jinetd;
2 import org.ibex.util.*;
3 import org.ibex.io.*;
4 import java.io.*;
5 import java.util.*;
6 import java.net.*;
7 import java.util.zip.*;
8
9 public class Port extends Loader {
10
11     private final NetworkInterface iface;
12     private final int port;
13     private final Thread listener;
14
15     public Port(String path, NetworkInterface iface, int port) {
16         super(path);
17         this.iface = iface;
18         this.port = port;
19         this.listener = new PortThread();
20         listener.start();
21     }
22
23     public void changed(Watched w) {
24         //Log.warn(this, "Port: noticed change in " + w);
25         super.changed(w);
26     }
27
28     void dispatch(final Connection conn) throws Exception {
29         getClassLoader();
30         String[] list = list();
31         for(int i=0; i<list.length; i++) {
32             if (!list[i].endsWith(".jar")) continue;
33             //Log.warn(this, "checking " + (this.path + File.separatorChar + list[i]));
34             File f = new File(this.path + File.separatorChar + list[i]);
35             ZipInputStream zis = new ZipInputStream(new FileInputStream(f));
36             for(ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
37                 String name = ze.getName();
38                 if (name.endsWith(".class"))
39                     dispatch(conn, name.substring(0, name.length() - ".class".length()).replace('/', '.'));
40             }
41         }
42         check(conn, new File(getAbsolutePath() + File.separatorChar + "BIN"));
43     }
44
45     void check(Connection conn, File f) throws Exception {
46         //Log.warn(this, "check(" + f.getAbsolutePath() + ")");
47         if (!f.exists()) return;
48         if (!f.isDirectory()) {
49             if (!f.getAbsolutePath().endsWith(".class")) return;
50             String name = f.getAbsolutePath().substring(getAbsolutePath().length() + 5);
51             name = name.substring(0, name.length() - ".class".length()).replace(File.separatorChar, '.');
52             dispatch(conn, name);
53         } else {
54             String[] list = f.list();
55             for(int i=0; i<list.length; i++) check(conn, new File(f.getAbsolutePath() + File.separatorChar + list[i]));
56         }
57     }
58     void dispatch(final Connection conn, String name) throws Exception {
59         //Log.info(this, "attempting class " + name);
60         try {
61             Class c = getClassLoader().loadClass(name);
62             if (c != null) {
63                 if (Listener.class.isAssignableFrom(c)) {
64                     Log.error(this, "dispatching connection on port " + port + " to " +
65                               c.getName());
66                     final Listener l = (Listener)c.newInstance();
67                     new Thread() { public void run() {
68                         Log.clearnotes();
69                         try {
70                             l.accept(conn);
71                         } catch (Exception e) {
72                             Log.error(l.getClass(), "Listener threw exception");
73                             Log.error(l.getClass(), e);
74                         } finally {
75                             conn.close();
76                         }
77                     } }.start();
78                     return;
79                 }
80             }
81         } catch (Exception e) {
82             Log.error(this, e);
83         }
84     }
85
86     private class PortThread extends Thread {
87         public void run() {
88             try {
89                 Log.warn(this, "Now listening on interface " + iface + ", port " + port);
90                 ServerSocket ss = new ServerSocket(port);
91                 for(Socket s = ss.accept(); ; s = ss.accept()) try {
92                     Log.warn(this, "accepted connection on port " + port);
93                     dispatch(new Connection(s, "megacz.com"));
94                     Log.warn(this, "done searching for service on port " + port);
95                 } catch (Exception e) { Log.warn(Port.class, e); }
96             } catch (Exception e) { Log.error(Port.class, e);
97             } catch (Throwable t) {
98                 Log.error(this, "serious error, aborting VM");
99                 Log.error(this, t);
100                 Root.reboot();
101             }
102         }
103     }
104 }