moved to better jinetd setup
authoradam <adam@megacz.com>
Mon, 16 Aug 2004 00:01:20 +0000 (00:01 +0000)
committeradam <adam@megacz.com>
Mon, 16 Aug 2004 00:01:20 +0000 (00:01 +0000)
darcs-hash:20040816000120-5007d-f4656e5627097b60a073c7316e81a438cceba006.gz

src/org/ibex/jinetd/Loader.java
src/org/ibex/jinetd/Main.java
src/org/ibex/jinetd/Port.java
src/org/ibex/jinetd/Root.java
src/org/ibex/jinetd/Watched.java
www/index.html

index b166df6..96093bd 100644 (file)
@@ -11,10 +11,14 @@ public class Loader extends Watcher {
 
     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) {
@@ -28,7 +32,6 @@ public class Loader extends Watcher {
                     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);
@@ -52,6 +55,7 @@ public class Loader extends Watcher {
         }
     }
 
+
     public String getClassPath() {
         String classpath = System.getProperty("java.class.path");
         String [] l = new File(Root.root + "/LIB/").list();
@@ -122,7 +126,7 @@ public class Loader extends Watcher {
             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() {
@@ -147,6 +151,12 @@ public class Loader extends Watcher {
     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;
         }
index a8ae366..c2cb324 100644 (file)
@@ -1,10 +1,63 @@
 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);
index 037a801..d7f850d 100644 (file)
@@ -71,7 +71,7 @@ public class Port extends Loader {
             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 {
@@ -83,7 +83,7 @@ public class Port extends Loader {
                 } finally {
                     conn.close();
                 }
-            } }.start();
+            } }).start();
             return true;
         } catch (Exception e) { Log.error(this, e); }
         return false;
index d8ccc36..9c2fa93 100644 (file)
@@ -6,7 +6,7 @@ import java.net.*;
 
 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;
 
@@ -20,6 +20,7 @@ public class Root extends Loader {
         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;
     }
 
@@ -33,7 +34,7 @@ public class Root extends Loader {
             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();
index 5d280c6..197f7dd 100644 (file)
@@ -28,11 +28,15 @@ public class Watched extends File {
         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();
+            }
         }
     }
 
index 347ed17..943fbe9 100644 (file)
@@ -10,10 +10,12 @@ Jinetd does for TCP what servlet containers do for HTTP.
 <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>