ClassLoader parentClassLoader = null;
static final ClassLoader mycl = Loader.class.getClassLoader();
+
+ protected ThreadGroup tg = new ThreadGroup(getAbsolutePath());
+
public Loader(String path) { super(path); }
//public Loader(String path, ClassLoader pcl) { super(path); this.parentClassLoader = pcl; }
private TreeClassLoader classloader = null;
+ public synchronized void scan() throws IOException { super.scan(); }
public synchronized ClassLoader getClassLoader() {
ClassLoader classloader = this.classloader;
if (classloader == null) {
if (us.endsWith(".jar")) us = "file:"+us;
else us = "file:"+us+"/";
urls[i] = new URL(us);
- Log.warn("[classpath]", urls[i].toString());
}
} catch (MalformedURLException e) {
Log.error(this, e);
}
}
+
public String getClassPath() {
String classpath = System.getProperty("java.class.path");
String [] l = new File(Root.root + "/LIB/").list();
String[] all = new String[args.size()];
args.copyInto(all);
Log.info(this, "invoking javac for " + srcdir.getAbsolutePath());
- final Process javac = Runtime.getRuntime().exec(all);
+ final Process javac = Runtime.getRuntime().exec(all, new String[] { "PATH=/bin:/usr/bin" });
final BufferedReader out = new BufferedReader(new InputStreamReader(javac.getInputStream()));
final BufferedReader err = new BufferedReader(new InputStreamReader(javac.getErrorStream()));
new Thread() { public void run() {
public void changed(Watched w) {
if (w.path.indexOf("BIN") != -1) return;
if (classloader != null) {
+ Log.info(this, "killing all threads for: " + w.path);
+ Log.info(this, " thread count before kill: " + tg.activeCount());
+ tg.interrupt();
+ try { Thread.sleep(1000); } catch (Exception e) { }
+ Log.info(this, " thread count after kill: " + tg.activeCount());
+ tg = new ThreadGroup(getAbsolutePath());
Log.info(this, "scheduling classes for reload due to change in: " + w.path);
classloader = null;
}
package org.ibex.jinetd;
import org.ibex.util.*;
import java.io.*;
+import java.net.*;
import java.util.*;
+import java.util.zip.*;
public class Main {
+ public static String ROOT;
+ public static String LOGFILE;
+ public static PrintStream LOGSTREAM;
+
+ private static void configureRoot() throws Exception {
+ ROOT = System.getProperty("jinetd.root", null);
+ if (ROOT == null) {
+ ROOT = autoDetectRoot();
+ System.setProperty("jinetd.root", ROOT);
+ }
+ }
+
+ private static void configureLogging() throws Exception {
+ LOGFILE = System.getProperty("jinetd.logfile", ROOT + File.separatorChar+"log.txt");
+ LOGSTREAM = new PrintStream(new FileOutputStream(LOGFILE, true));
+ System.setErr(LOGSTREAM);
+ System.setOut(LOGSTREAM);
+ }
+
+ private static String autoDetectRoot() throws Exception {
+ if (!(Main.class.getClassLoader() instanceof URLClassLoader))
+ throw new Error("unable to detect jinetd.root because my ClassLoader is not an instanceof URLClassLoader");
+ URL[] urls = ((URLClassLoader)Main.class.getClassLoader()).getURLs();
+ for(int i=0; i<urls.length; i++) {
+ if (!urls[i].getProtocol().equals("file")) continue;
+ File file = new File(urls[i].getPath());
+ if (file.isDirectory()) {
+ if (new File(file.getAbsolutePath() +
+ File.separatorChar +
+ Main.class.getName().replace('.', File.separatorChar)+".class").exists())
+ return file.getAbsolutePath();
+ } else if (file.getAbsolutePath().endsWith(".jar")) {
+ ZipFile zf = new ZipFile(file);
+ if (zf.getEntry(Main.class.getName().replace('.', File.separatorChar)+".class") != null)
+ return new File(file.getParent()).getAbsolutePath();
+ }
+ }
+ throw new Error("unable to detect jinetd.root because " +
+ Main.class.getName() +
+ " was not in any of the ClassLoader URLs");
+ }
+
+ static {
+ try {
+ configureRoot();
+ configureLogging();
+ } catch (Throwable e) {
+ throw new Error(e);
+ }
+ }
+
public static void main(String[] s) throws Exception {
Log.color = true;
Root root = new Root(Root.root);
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() { public void run() {
+ new Thread(tg, new Runnable() { public void run() {
Log.clearnotes();
Thread.currentThread().setContextClassLoader(cl);
try {
} finally {
conn.close();
}
- } }.start();
+ } }).start();
return true;
} catch (Exception e) { Log.error(this, e); }
return false;
public class Root extends Loader {
- public static String root = System.getProperty("jinetd.root", "/jinetd");
+ public static String root = System.getProperty("jinetd.root", null);
private final Host host;
private final Watched port;
if (part.equals("host")) return host;
if (part.equals("port")) return port;
if (part.equals("LIB")) return super.slash(part);
+ if (part.endsWith(".jar")) return super.slash(part);
return null;
}
Log.debug(this, "/host changed");
} else if (w.part.equals("port")) {
Log.debug(this, "/port changed");
- } else if (w.getAbsolutePath().startsWith(Root.root + "/LIB/")) {
+ } else if (w.getAbsolutePath().endsWith(".jar")) {
if (w.lastModifiedAtLastScan != -1) {
Log.error(this, "jinetd upgraded; bouncing the JVM....");
reboot();
String[] kids = list();
if (kids == null) return;
for(int i=0; i<kids.length; i++) {
- if (cache.get(kids[i]) != null) continue;
- Watched kid = slash(kids[i]);
- if (kid == null) continue;
- cache.put(kids[i], kid);
- watcher().changed(kid);
+ Watched kid = (Watched)cache.get(kids[i]);
+ if (kid == null) {
+ kid = slash(kids[i]);
+ if (kid == null) continue;
+ cache.put(kids[i], kid);
+ watcher().changed(kid);
+ } else {
+ kid.scan();
+ }
}
}
<h3> Isn't HTTP all that matters? </h3>
There are now Java servers for almost every network protocol: HTTP,
-SMTP, IMAP, POP3, NNTP, DNS, SSH, CIFS/SMB, and plenty of others.
-Using servers written in buffer-overflow-free languages is the most
-important step towards maintaining network security and stopping
-worms.
+SMTP, IMAP, POP3, NNTP, DNS, <a
+href=http://www.jcraft.com/jsch/>SSH</a>, <a
+href=http://telnetd.sourceforge.net/index.html>TELNET</a>, CIFS/SMB,
+and plenty of others. Using servers written in buffer-overflow-free
+languages is the most important step towards maintaining network
+security and stopping worms.
<h3> Huh? </h3>