From owner-freebsd-hackers Mon Mar 3 20:20:17 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id UAA21728 for hackers-outgoing; Mon, 3 Mar 1997 20:20:17 -0800 (PST) Received: from obiwan.aceonline.com.au (obiwan.aceonline.com.au [203.103.90.67]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id UAA21558; Mon, 3 Mar 1997 20:16:41 -0800 (PST) Received: from localhost (adrian@localhost) by obiwan.aceonline.com.au (8.8.5/8.8.5) with SMTP id SAA02177; Tue, 4 Mar 1997 18:19:38 +0800 (WST) Date: Tue, 4 Mar 1997 18:19:38 +0800 (WST) From: Adrian Chadd To: hackers@freebsd.org, emulation@freebsd.org Subject: Re : latest Java support source for FreeBSD.. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Ok here it is. If people like the idea of making it a lkm, then combine it with joerg's lkm patch and go from there. Test it, find bugs, and tell me asap so I can go forth and fix them.. this might be a good addition to the 2.2-rel *grin* Also - I'll finish the appletviewer support tonight. Adrian. -- Begin /usr/sys/sys/kern/imgact_jave.c /*- * Copyright (c) 1997 Adrian Chadd * All rights reserved. * * Based heavily on /sys/kern/imgact_shell.c which is: * Copyright (c) 1993, David Greenman * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software withough specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include /* Lets set up reasonable defaults for the system variables ** kern.java.interpreter and kern.java.appletviewer */ static char interpreter[256] = "/usr/local/jdk/bin/i386/java"; static char appletviewer[256] = "/usr/local/jdk/bin/i386/appletviewer"; static char classpath[256] = "/usr/local/jdk/classes:/usr/local/jdk/lib/classes.zip"; SYSCTL_NODE(_kern, OID_AUTO, java, CTLFLAG_RW, 0, "Kernel Java support"); SYSCTL_STRING(_kern_java, OID_AUTO, interpreter, CTLFLAG_RW, interpreter, sizeof(interpreter), "Path to Java interpreter"); SYSCTL_STRING(_kern_java, OID_AUTO, appletviewer, CTLFLAG_RW, appletviewer, sizeof(appletviewer), "Path to Java appletviewer"); SYSCTL_STRING(_kern_java, OID_AUTO, classpath, CTLFLAG_RW, classpath, sizeof(classpath), "Path to Java classes"); extern int exec_java_imgact __P((struct image_params *iparams)); int dirname(const char *, char *, int); int basename(const char *, char *, int); char * strstr(const char *, const char *); /* Some utility crap */ int dirname(const char *string, char *newstring, int maxlen) { char *p; int ch; char str[256]; strncpy(str, string, 250); str[250] = '\0'; /* * (1) If string is //, skip steps (2) through (5). * (2) If string consists entirely of slash characters, string * shall be set to a single slash character. In this case, * skip steps (3) through (8). */ for (p = str;; ++p) { if (!*p) { if (p > str) (void)strcpy(newstring, "/"); else (void)strcpy(newstring, "."); return(0); } if (*p != '/') break; } /* * (3) If there are any trailing slash characters in string, they * shall be removed. */ for (; *p; ++p); while (*--p == '/') continue; *++p = '\0'; /* * (4) If there are no slash characters remaining in string, * string shall be set to a single period character. In this * case skip steps (5) through (8). * * (5) If there are any trailing nonslash characters in string, * they shall be removed. */ while (--p >= str) if (*p == '/') break; ++p; if (p == str) { (void)strcpy(newstring, "."); return(0); } /* * (6) If the remaining string is //, it is implementation defined * whether steps (7) and (8) are skipped or processed. * * This case has already been handled, as part of steps (1) and (2). */ /* * (7) If there are any trailing slash characters in string, they * shall be removed. */ while (--p >= str) if (*p != '/') break; ++p; /* * (8) If the remaining string is empty, string shall be set to * a single slash character. */ *p = '\0'; if (p == str) { strcpy(newstring, "/"); } else { strncpy(newstring, str, maxlen); newstring[maxlen] = '\0'; } return(0); } int basename(const char *string, char *newstring, int maxlen) { int ch; char *p; char str[256]; strncpy(str, string, 250); str[250] = '\0'; /* * (1) If string is // it is implementation defined whether steps (2) * through (5) are skipped or processed. * * (2) If string consists entirely of slash characters, string shall * be set to a single slash character. In this case, skip steps * (3) through (5). */ for (p = str;; ++p) { if (!*p) { if (p > str) (void)strcpy(newstring, "/"); else (void)strcpy(newstring, ""); return(0); } if (*p != '/') break; } /* * (3) If there are any trailing slash characters in string, they * shall be removed. */ for (; *p; ++p) continue; while (*--p == '/') continue; *++p = '\0'; /* * (4) If there are any slash characters remaining in string, the * prefix of string up to an including the last slash character * in string shall be removed. */ while (--p >= str) if (*p == '/') break; ++p; /* * (5) If the suffix operand is present, is not identical to the * characters remaining in string, and is identical to a suffix * of the characters remaining in string, the suffix suffix * shall be removed from string. */ if (++*str) { int suffixlen, stringlen, off; suffixlen = strlen(str); stringlen = strlen(p); if (suffixlen < stringlen) { off = stringlen - suffixlen; if (!strcmp(p + off, str)) p[off] = '\0'; } } (void)strncpy(newstring, p, maxlen); return(0); } /* * Find the first occurrence of find in s. */ char * strstr(s, find) register const char *s, *find; { register char c, sc; register size_t len; if ((c = *find++) != 0) { len = strlen(find); do { do { if ((sc = *s++) == 0) return (NULL); } while (sc != c); } while (strncmp(s, find, len) != 0); s--; } return ((char *)s); } /* The real thing */ int exec_java_imgact(imgp) struct image_params *imgp; { const char *image_header = imgp->image_header; const char *ihp, *line_endp; char *interp; static char javabin_name[256]; static char javabin_path[256]; static char cpathstr[256]; static char javatmp[256]; /* A java binary? */ if ((image_header[0] != '\xca') || (image_header[1] != '\xfe') || (image_header[2] != '\xba') || (image_header[3] != '\xbe')) { #ifdef DEBUG printf("Failed to run a java binary : invalid signature?\n"); return(-1); #endif } /* Ok, its a java binary, so lets tell the world */ /* Firstly split the path to the binary up into path and filename */ basename(imgp->uap->fname, javabin_name, sizeof(javabin_name)); dirname(imgp->uap->fname, javabin_path, sizeof(javabin_path)); /* Now we are going to take the filename, and if it doesn't contain ** a .class then return with a "non-executable" error */ if (strstr(javabin_name, ".class") == NULL) { return -1; } /* Ok so we'll assume (stupidly) that the .class is at the end of the ** filename, so lets copy the filename over minus the last 6 chars */ strncpy(javatmp, javabin_name, strlen(javabin_name) - 6); strcpy(javabin_name, javatmp); /* Since its interpreted we'll tag it as such. */ imgp->interpreted = 1; /* And we'll set the interpreter name here too (would help) */ strncpy(imgp->interpreter_name, interpreter, sizeof(imgp->interpreter_name)); /* now lets make up our -classpath arguement */ sprintf(cpathstr, "%s -classpath %s:%s", interpreter, classpath, javabin_path); /* Now lets write this into the strings space, just like in the ** _shell.c file... */ ihp = cpathstr; line_endp = cpathstr + strlen(cpathstr); while (ihp < line_endp) { while ((*ihp == ' ') || (*ihp == '\t')) ihp++; if (ihp < line_endp) { while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) { *imgp->stringp++ = *ihp++; imgp->stringspace--; } *imgp->stringp++ = 0; imgp->stringspace--; imgp->argc++; } } strcpy(imgp->uap->fname, javabin_name); suword(imgp->uap->argv, (int)imgp->uap->fname); return (0); } /* * Tell kern_execve.c about it, with a little help from the linker. * Since `const' objects end up in the text segment, TEXT_SET is the * correct directive to use. */ const struct execsw java_execsw = { exec_java_imgact, "\xca\xfe\xba\xbe" }; TEXT_SET(execsw_set, java_execsw);