Skip site navigation (1)Skip section navigation (2)
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>