Date: Tue, 4 Mar 1997 18:19:38 +0800 (WST) From: Adrian Chadd <adrian@obiwan.aceonline.com.au> To: hackers@freebsd.org, emulation@freebsd.org Subject: Re : latest Java support source for FreeBSD.. Message-ID: <Pine.BSF.3.95q.970304181657.2164C-100000@obiwan.aceonline.com.au>
next in thread | raw e-mail | index | archive | help
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 <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/resourcevar.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
#include <machine/endian.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
/* 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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.95q.970304181657.2164C-100000>
