+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
package org.ibex.jinetd;
import org.ibex.util.*;
import org.ibex.io.*;
import java.net.*;
import java.util.zip.*;
-public class Port extends Loader {
+// Feature: port-level redirects
+public class Port extends TreeClassLoader {
+ final ThreadPool tp;
final InetAddress bindTo;
final int port;
private static Hash cache = new Hash();
- public static Port newPort(String path, InetAddress bindTo, int port) throws IOException {
+ public static Port newPort(String path, InetAddress bindTo, int port, ThreadPool tp) throws IOException {
String canonical = new File(path).getCanonicalPath();
Port p = (Port)cache.get(canonical);
- if (p == null) cache.put(canonical, p = new Port(path, bindTo, port));
+ if (p == null) cache.put(canonical, p = new Port(path, bindTo, port, tp));
else Log.warn(Port.class, " sharing " + bindTo+":"+port+" -> "+ (p.bindTo+":"+p.port));
p.spawn(bindTo, port);
return p;
}
void spawn(InetAddress bindTo, int port) { new PortThread(bindTo, port).start(); }
- private Port(String path, InetAddress bindTo, int port) {
- super(path);
- this.bindTo = bindTo;
- this.port = port;
- }
-
- public void changed(Watched w) {
- //Log.warn(this, "Port: noticed change in " + w);
- super.changed(w);
- }
-
-
- 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++) {
- if (!list[i].endsWith(".jar")) continue;
- //Log.warn(this, "checking " + (this.path + File.separatorChar + list[i]));
- File f = new File(this.path + File.separatorChar + list[i]);
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(f);
- ZipInputStream zis = new ZipInputStream(fis);
- for(ZipEntry ze = zis.getNextEntry(); ze != null; ze = zis.getNextEntry()) {
- String name = ze.getName();
- 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(); }
- }
- return findListener(new File(getAbsolutePath() + File.separatorChar + "BIN"));
- }
-
- Class findListener(File f) throws Exception {
- if (!f.exists()) return null;
- if (!f.isDirectory()) {
- 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, '.');
- Class c = isListener(name);
- if (c != null) return c;
- } else {
- String[] list = f.list();
- 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 null;
- }
+ private static final ClassLoader parentLoader = Main.getRootClassLoader();
+ private Port(String path, InetAddress bindTo, int port, ThreadPool tp) {
+ super(new File(path), parentLoader);
+ this.bindTo = bindTo; this.port = port; this.tp = tp; }
void dispatch(final Connection conn) throws Exception {
- new Thread(tg, new Runnable() { public void run() {
+ tp.appendTask(new Runnable() { public void run() {
String local = conn.getLocalAddress() + ":" + conn.getLocalPort();
String remote = conn.getRemoteHostname() + ":" + conn.getRemotePort();
try {
- Class c = findListener();
+ // FIXME FIXME
+ Class c = loadClass("org.ibex.mail.Main");
if (c == null) throw new RuntimeException("couldn't find listener");
- Log.info("["+local+"]", "connection from " + remote + " => " + c.getName());
+ Log.info("["+local+"]", "connection from " + remote + " => " + c.getName() + ":"+conn.getLocalPort());
Log.clearnotes();
- final ClassLoader cl = getClassLoader();
- Thread.currentThread().setContextClassLoader(cl);
+ Thread.currentThread().setContextClassLoader(Port.this);
Listener l = (Listener)c.newInstance();
l.accept(conn);
} catch (org.ibex.io.Stream.EOF eof) {
} finally {
conn.close();
}
- } }).start();
+ } });
}
private class PortThread extends Thread {
public PortThread(InetAddress bindTo, int port) { this.bindTo = bindTo; this.port = port; }
public void run() {
try {
- Log.warn(this, "Now listening on address " + (bindTo == null ? "all interfaces" : bindTo.toString()) +
- ", port " + port);
+ Log.warn(this, "Now listening on address " + (bindTo==null?"all interfaces":bindTo.toString()) + ", port " + port);
ServerSocket ss = bindTo == null ? new ServerSocket(port) : new ServerSocket(port, 0, bindTo);
for(Socket s = ss.accept(); ; s = ss.accept()) try {
- dispatch(new Connection(s, "megacz.com"));
+ dispatch(new Connection(s, Main.defaultDomain));
} catch (Exception e) { Log.warn(Port.class, e); }
} catch (Exception e) { Log.error(Port.class, e);
} catch (Throwable t) {
Log.error(this, "serious error, aborting VM");
Log.error(this, t);
- Root.reboot();
+ Main.reboot();
}
}
}