https://wiki.archlinux.org/api.php?action=feedcontributions&user=Alterkacker&feedformat=atomArchWiki - User contributions [en]2024-03-29T05:47:52ZUser contributionsMediaWiki 1.41.0https://wiki.archlinux.org/index.php?title=Clean_Cache&diff=67890Clean Cache2009-04-29T19:31:06Z<p>Alterkacker: Now handles both i686 & x86_64 architecture identifier in name</p>
<hr />
<div>[[Category:Package management (English)]]<br />
[[Category:Scripts (English)]]<br />
[[Category:General (English)]]<br />
''Contributor: alterkacker''<br />
<br />
http://bbs.archlinux.org/viewtopic.php?t=9104<br />
Here is a python script to clean the <code>/var/cache/pacman/pkg</code> directory while allowing you to specify how many package versions should be retained.<br />
<br />
<pre><br />
#!/usr/bin/env python<br />
"""cache_clean - a simple python script to clean up the /var/cache/pacman/pkg directory.<br />
More versatile than 'pacman -Sc' in that you can select how many old versions<br />
to keep.<br />
Usage: cache_clean {-p} {-v} <# of copies to keep><br />
# of copies to keep - (required) how many generations of each package to keep<br />
-p - (optional) preview what would be deleted; forces verbose (-v) mode.<br />
-v - (optional) show deleted packages."""<br />
# Note that the determination of package age is done by simply looking at the date-time<br />
# modified stamp on the file. There is just enough variation in the way package version<br />
# is done that I thought this would be simpler & just as good.<br />
# Also note that you must be root to run this script.<br />
<br />
import getopt<br />
import os<br />
import re<br />
import sys<br />
<br />
# helper function to get tuple of (file dtm, file name, file sz) <br />
def fn_stats(fn):<br />
s = os.stat(fn)<br />
return (s[8], fn, s[6])<br />
<br />
# cleanup does the actual pkg file deletion<br />
def cleanup(run_list):<br />
# strictly speaking only the first two of these globals need to be listed.<br />
global n_deleted, bytes_deleted, opt_verbose, opt_preview, n_to_keep<br />
# return if the run_list is too short<br />
#print run_list<br />
#return<br />
if len(run_list) <= n_to_keep: return<br />
# Build list of tuples (date-time file modified, file name, file size)<br />
dtm_list = [fn_stats(tfn) for tfn in run_list]<br />
# Sort the list by date-time<br />
dtm_list.sort()<br />
# Build list of the filenames to delete (all but last n_to_keep).<br />
# <showing_off><br />
#kill_list = [tfn[1] for tfn in dtm_list[:-n_to_keep]]<br />
#bytes_deleted = reduce(lambda x, y: x+y, [x[2] for x in dtm_list[:-n_to_keep]])<br />
# </showing_off><br />
kill_list = []<br />
for x in dtm_list[:-n_to_keep]:<br />
kill_list.append(x[1])<br />
bytes_deleted += x[2]<br />
if opt_verbose: print kill_list<br />
n_deleted += len(kill_list)<br />
# and finally delete (if not in preview mode)<br />
if not opt_preview:<br />
for dfn in kill_list:<br />
os.unlink(dfn)<br />
<br />
######################################################################<br />
# mainline processing<br />
<br />
# process command line options<br />
try:<br />
opts, pargs = getopt.getopt(sys.argv[1:], 'vp')<br />
opt_dict = dict(opts)<br />
opt_preview = opt_dict.has_key('-p')<br />
opt_verbose = opt_dict.has_key('-v')<br />
if opt_preview: opt_verbose = True<br />
if len(pargs) == 1:<br />
n_to_keep = pargs[0]<br />
else:<br />
raise getopt.GetoptError("missing required argument.")<br />
try:<br />
n_to_keep = int(n_to_keep)<br />
if n_to_keep <= 0: raise ValueError<br />
except ValueError, e:<br />
raise getopt.GetoptError("# of copies to keep must be numeric > 0!")<br />
except getopt.GetoptError, msg:<br />
print "Error:",msg,"\n",__doc__<br />
sys.exit(1)<br />
<br />
# change to the pkg directory & get a sorted list of its contents<br />
os.chdir('/var/cache/pacman/pkg')<br />
pkg_fns = os.listdir('.')<br />
pkg_fns.sort()<br />
<br />
# Pattern to use to extract the package name from the tar file name:<br />
# for pkg e.g. 'gnome-common-2.8.0-1-i686.pkg.tar.gz' group(1) is 'gnome-common'.<br />
bpat = re.compile(r'^(.+)-\d[^-]+-.+?(-i686|-x86_64)?\.pkg\.tar\.gz$')<br />
<br />
n_deleted = 0<br />
bytes_deleted = 0<br />
pkg_base_nm = ''<br />
# now look for "runs" of the same package name differing only in version info.<br />
for run_end in range(len(pkg_fns)):<br />
fn = pkg_fns[run_end]<br />
mo = bpat.match(fn) # test for a match of the package name pattern<br />
if mo:<br />
tbase = mo.group(1) # gets the 'base' package name<br />
# include the architecture in the name if it's present<br />
if mo.lastindex > 1:<br />
tbase += mo.group(2)<br />
#print 'tbase: ',tbase,' ',mo.lastindex<br />
# is it a new base name, i.e. the start of a new run?<br />
if tbase != pkg_base_nm: # if so then process the prior run<br />
if pkg_base_nm != '':<br />
cleanup(pkg_fns[run_start:run_end])<br />
pkg_base_nm = tbase # & setup for the new run<br />
run_start = run_end<br />
else:<br />
print >>sys.stderr, "File '"+fn+"' doesn't match package pattern!"<br />
<br />
# catch the final run of the list<br />
run_end += 1<br />
cleanup(pkg_fns[run_start:run_end])<br />
<br />
if opt_verbose:<br />
if opt_preview:<br />
print "Preview mode (no files deleted):",<br />
print n_deleted,"files deleted,",bytes_deleted/1000,"kbytes."</pre></div>Alterkackerhttps://wiki.archlinux.org/index.php?title=Clean_Cache&diff=67888Clean Cache2009-04-29T18:52:55Z<p>Alterkacker: New version of the script</p>
<hr />
<div>[[Category:Package management (English)]]<br />
[[Category:Scripts (English)]]<br />
[[Category:General (English)]]<br />
''Contributor: alterkacker''<br />
<br />
http://bbs.archlinux.org/viewtopic.php?t=9104<br />
Here is a python script to clean the <code>/var/cache/pacman/pkg</code> directory while allowing you to specify how many package versions should be retained.<br />
<br />
<pre><br />
#!/usr/bin/env python<br />
"""cache_clean - a simple python script to clean up the /var/cache/pacman/pkg directory.<br />
More versatile than 'pacman -Sc' in that you can select how many old versions<br />
to keep.<br />
Usage: cache_clean {-p} {-v} <# of copies to keep><br />
# of copies to keep - (required) how many generations of each package to keep<br />
-p - (optional) preview what would be deleted; forces verbose (-v) mode.<br />
-v - (optional) show deleted packages."""<br />
# Note that the determination of package age is done by simply looking at the date-time<br />
# modified stamp on the file. There is just enough variation in the way package version<br />
# is done that I thought this would be simpler & just as good.<br />
# Also note that you must be root to run this script.<br />
<br />
import getopt<br />
import os<br />
import re<br />
import sys<br />
<br />
# helper function to get tuple of (file dtm, file name, file sz) <br />
def fn_stats(fn):<br />
s = os.stat(fn)<br />
return (s[8], fn, s[6])<br />
<br />
# cleanup does the actual pkg file deletion<br />
def cleanup(run_list):<br />
# strictly speaking only the first two of these globals need to be listed.<br />
global n_deleted, bytes_deleted, opt_verbose, opt_preview, n_to_keep<br />
# return if the run_list is too short<br />
#print run_list<br />
#return<br />
if len(run_list) <= n_to_keep: return<br />
# Build list of tuples (date-time file modified, file name, file size)<br />
dtm_list = [fn_stats(tfn) for tfn in run_list]<br />
# Sort the list by date-time<br />
dtm_list.sort()<br />
# Build list of the filenames to delete (all but last n_to_keep).<br />
# <showing_off><br />
#kill_list = [tfn[1] for tfn in dtm_list[:-n_to_keep]]<br />
#bytes_deleted = reduce(lambda x, y: x+y, [x[2] for x in dtm_list[:-n_to_keep]])<br />
# </showing_off><br />
kill_list = []<br />
for x in dtm_list[:-n_to_keep]:<br />
kill_list.append(x[1])<br />
bytes_deleted += x[2]<br />
if opt_verbose: print kill_list<br />
n_deleted += len(kill_list)<br />
# and finally delete (if not in preview mode)<br />
if not opt_preview:<br />
for dfn in kill_list:<br />
os.unlink(dfn)<br />
<br />
######################################################################<br />
# mainline processing<br />
<br />
# process command line options<br />
try:<br />
opts, pargs = getopt.getopt(sys.argv[1:], 'vp')<br />
opt_dict = dict(opts)<br />
opt_preview = opt_dict.has_key('-p')<br />
opt_verbose = opt_dict.has_key('-v')<br />
if opt_preview: opt_verbose = True<br />
if len(pargs) == 1:<br />
n_to_keep = pargs[0]<br />
else:<br />
raise getopt.GetoptError("missing required argument.")<br />
try:<br />
n_to_keep = int(n_to_keep)<br />
if n_to_keep <= 0: raise ValueError<br />
except ValueError, e:<br />
raise getopt.GetoptError("# of copies to keep must be numeric > 0!")<br />
except getopt.GetoptError, msg:<br />
print "Error:",msg,"\n",__doc__<br />
sys.exit(1)<br />
<br />
# change to the pkg directory & get a sorted list of its contents<br />
os.chdir('/var/cache/pacman/pkg')<br />
pkg_fns = os.listdir('.')<br />
pkg_fns.sort()<br />
<br />
# Pattern to use to extract the package name from the tar file name:<br />
# for pkg e.g. 'gnome-common-2.8.0-1.pkg.tar.gz' group(1) is 'gnome-common'.<br />
bpat = re.compile(r'^(.+)-\d[^-]+-.+(-i686)?\.pkg\.tar\.gz$')<br />
<br />
n_deleted = 0<br />
bytes_deleted = 0<br />
pkg_base_nm = ''<br />
# now look for "runs" of the same package name differing only in version info.<br />
for run_end in range(len(pkg_fns)):<br />
fn = pkg_fns[run_end]<br />
mo = bpat.match(fn) # test for a match of the package name pattern<br />
if mo:<br />
tbase = mo.group(1) # gets the 'base' package name<br />
#print 'tbase: ',tbase<br />
# is it a new base name, i.e. the start of a new run?<br />
if tbase != pkg_base_nm: # if so then process the prior run<br />
if pkg_base_nm != '':<br />
cleanup(pkg_fns[run_start:run_end])<br />
pkg_base_nm = tbase # & setup for the new run<br />
run_start = run_end<br />
else:<br />
print >>sys.stderr, "File '"+fn+"' doesn't match package pattern!"<br />
<br />
# catch the final run of the list<br />
run_end += 1<br />
cleanup(pkg_fns[run_start:run_end])<br />
<br />
if opt_verbose:<br />
if opt_preview:<br />
print "Preview mode (no files deleted):",<br />
print n_deleted,"files deleted,",bytes_deleted/1000,"kbytes."</pre></div>Alterkackerhttps://wiki.archlinux.org/index.php?title=Binfmt_misc_for_Java&diff=67415Binfmt misc for Java2009-04-22T14:20:07Z<p>Alterkacker: Fix bug in jarwrapper (from the original)</p>
<hr />
<div>''This is a short tutorial on using Linux's binfmt_misc capability to make Java class and jar files easily executable from the command line.''<br />
=Introduction=<br />
''From [http://en.wikipedia.org/wiki/Binfmt_misc Wikipedia]:''<br />
<br />
"binfmt_misc is a capability of the Linux kernel which allows arbitrary executable file formats to be recognized and passed to certain user space applications, such as emulators and virtual machines."<br />
<br />
In plain language, this allows you to take a Java jar file that you would ordinarily run via a line such as<br />
java -jar /path/to/MyProgram.jar<br />
and instead run it simply with<br />
MyProgram.jar<br />
as long as it's on the PATH.<br />
<br />
The information in this article is almost entirely taken from the files '''binfmt_misc.txt''' and '''java.txt''' in the '''Documentation''' sub-directory of the Linux kernel source tree.<br />
=Setup=<br />
==Mounting binfmt_misc==<br />
For an ad-hoc mount:<br />
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc<br />
For a persistent mount via fstab add the line:<br />
none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0<br />
==Registering the file type with binfmt_misc==<br />
This is done by echoing a specially formatted line to '''/proc/sys/fs/binfmt_misc/register'''. The contents of the line is explained in the '''Documentation/binfmt_misc.txt''' file. To make the file registrations automatic at boot you can add the appropriate lines to your '''rc.local''' file, for example:<br />
# binfmt_misc support for Java applications:<br />
echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:' > /proc/sys/fs/binfmt_misc/register<br />
# binfmt_misc support for executable Jar files:<br />
echo ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:' > /proc/sys/fs/binfmt_misc/register<br />
# binfmt_misc support for Java Applets:<br />
echo ':Applet:E::html::/opt/bin/bin/appletviewer:' > /proc/sys/fs/binfmt_misc/register<br />
The first two of the above entries run Java class and jar files via <nowiki>'wrapper'</nowiki> scripts describe in the next section. The final entry runs Java applets in the usual way. You may reboot or run the file to put the registrations into effect immediately.<br />
==The wrapper scripts==<br />
===jarwrapper===<br />
#!/bin/bash<br />
# /usr/local/bin/jarwrapper - the wrapper for binfmt_misc/jar<br />
<br />
# set path to java using JAVA_HOME if available, otherwise assume it's on the PATH<br />
JAVA_PATH=${JAVA_HOME:+$JAVA_HOME/jre/bin/}java<br />
$JAVA_PATH -jar "$@"<br />
===javawrapper===<br />
#!/bin/bash<br />
# /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java<br />
<br />
if [ -z "$1" ]; then<br />
exec 1>&2<br />
echo Usage: $0 class-file<br />
exit 1<br />
fi<br />
<br />
CLASS=$1<br />
FQCLASS=`/usr/local/bin/javaclassname $1`<br />
FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'`<br />
FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'`<br />
<br />
# for example:<br />
# CLASS=Test.class<br />
# FQCLASS=foo.bar.Test<br />
# FQCLASSN=Test<br />
# FQCLASSP=foo/bar<br />
<br />
unset CLASSBASE<br />
<br />
declare -i LINKLEVEL=0<br />
<br />
while :; do<br />
if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then<br />
# See if this directory works straight off<br />
cd -L `dirname $CLASS`<br />
CLASSDIR=$PWD<br />
cd $OLDPWD<br />
if echo $CLASSDIR | grep -q "$FQCLASSP$"; then<br />
CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`<br />
break;<br />
fi<br />
# Try dereferencing the directory name<br />
cd -P `dirname $CLASS`<br />
CLASSDIR=$PWD<br />
cd $OLDPWD<br />
if echo $CLASSDIR | grep -q "$FQCLASSP$"; then<br />
CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`<br />
break;<br />
fi<br />
# If no other possible filename exists<br />
if [ ! -L $CLASS ]; then<br />
exec 1>&2<br />
echo $0:<br />
echo " $CLASS should be in a" \<br />
"directory tree called $FQCLASSP"<br />
exit 1<br />
fi<br />
fi<br />
if [ ! -L $CLASS ]; then break; fi<br />
# Go down one more level of symbolic links<br />
let LINKLEVEL+=1<br />
if [ $LINKLEVEL -gt 5 ]; then<br />
exec 1>&2<br />
echo $0:<br />
echo " Too many symbolic links encountered"<br />
exit 1<br />
fi<br />
CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`<br />
done<br />
<br />
if [ -z "$CLASSBASE" ]; then<br />
if [ -z "$FQCLASSP" ]; then<br />
GOODNAME=$FQCLASSN.class<br />
else<br />
GOODNAME=$FQCLASSP/$FQCLASSN.class<br />
fi<br />
exec 1>&2<br />
echo $0:<br />
echo " $FQCLASS should be in a file called $GOODNAME"<br />
exit 1<br />
fi<br />
<br />
if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then<br />
# class is not in CLASSPATH, so prepend dir of class to CLASSPATH<br />
if [ -z "${CLASSPATH}" ] ; then==<br />
export CLASSPATH=$CLASSBASE<br />
else<br />
export CLASSPATH=$CLASSBASE:$CLASSPATH<br />
fi<br />
fi<br />
<br />
shift<br />
# set path to java using JAVA_HOME if available, otherwise assume it's on the PATH<br />
JAVA_PATH=${JAVA_HOME:+$JAVA_HOME/jre/bin/}java<br />
$JAVA_PATH $FQCLASS "$@"<br />
===javaclassname===<br />
This program is used by the '''javawrapper''' script above. Compile it with the command<br />
gcc -O2 -o javaclassname javaclassname.c<br />
and move the executable to /usr/local/bin.<br />
/* javaclassname.c<br />
*<br />
* Extracts the class name from a Java class file; intended for use in a Java<br />
* wrapper of the type supported by the binfmt_misc option in the Linux kernel.<br />
*<br />
* Copyright (C) 1999 Colin J. Watson <cjw44@cam.ac.uk>.<br />
*<br />
* This program is free software; you can redistribute it and/or modify<br />
* it under the terms of the GNU General Public License as published by<br />
* the Free Software Foundation; either version 2 of the License, or<br />
* (at your option) any later version.<br />
*<br />
* This program is distributed in the hope that it will be useful,<br />
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
* GNU General Public License for more details.<br />
*<br />
* You should have received a copy of the GNU General Public License<br />
* along with this program; if not, write to the Free Software<br />
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
*/<br />
<br />
#include <stdlib.h><br />
#include <stdio.h><br />
#include <stdarg.h><br />
#include <sys/types.h><br />
<br />
/* From Sun's Java VM Specification, as tag entries in the constant pool. */<br />
<br />
#define CP_UTF8 1<br />
#define CP_INTEGER 3<br />
#define CP_FLOAT 4<br />
#define CP_LONG 5<br />
#define CP_DOUBLE 6<br />
#define CP_CLASS 7<br />
#define CP_STRING 8<br />
#define CP_FIELDREF 9<br />
#define CP_METHODREF 10<br />
#define CP_INTERFACEMETHODREF 11<br />
#define CP_NAMEANDTYPE 12<br />
<br />
/* Define some commonly used error messages */<br />
<br />
#define seek_error() error("%s: Cannot seek\n", program)<br />
#define corrupt_error() error("%s: Class file corrupt\n", program)<br />
#define eof_error() error("%s: Unexpected end of file\n", program)<br />
#define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);<br />
<br />
char *program;<br />
<br />
long *pool;<br />
<br />
u_int8_t read_8(FILE *classfile);<br />
u_int16_t read_16(FILE *classfile);<br />
void skip_constant(FILE *classfile, u_int16_t *cur);<br />
void error(const char *format, ...);<br />
int main(int argc, char **argv);<br />
<br />
/* Reads in an unsigned 8-bit integer. */<br />
u_int8_t read_8(FILE *classfile)<br />
{<br />
int b = fgetc(classfile);<br />
if(b == EOF)<br />
eof_error();<br />
return (u_int8_t)b;<br />
}<br />
<br />
/* Reads in an unsigned 16-bit integer. */<br />
u_int16_t read_16(FILE *classfile)<br />
{<br />
int b1, b2;<br />
b1 = fgetc(classfile);<br />
if(b1 == EOF)<br />
eof_error();<br />
b2 = fgetc(classfile);<br />
if(b2 == EOF)<br />
eof_error();<br />
return (u_int16_t)((b1 << 8) | b2);<br />
}<br />
<br />
/* Reads in a value from the constant pool. */<br />
void skip_constant(FILE *classfile, u_int16_t *cur)<br />
{<br />
u_int16_t len;<br />
int seekerr = 1;<br />
pool[*cur] = ftell(classfile);<br />
switch(read_8(classfile))<br />
{<br />
case CP_UTF8:<br />
len = read_16(classfile);<br />
seekerr = fseek(classfile, len, SEEK_CUR);<br />
break;<br />
case CP_CLASS:<br />
case CP_STRING:<br />
seekerr = fseek(classfile, 2, SEEK_CUR);<br />
break;<br />
case CP_INTEGER:<br />
case CP_FLOAT:<br />
case CP_FIELDREF:<br />
case CP_METHODREF:<br />
case CP_INTERFACEMETHODREF:<br />
case CP_NAMEANDTYPE:<br />
seekerr = fseek(classfile, 4, SEEK_CUR);<br />
break;<br />
case CP_LONG:<br />
case CP_DOUBLE:<br />
seekerr = fseek(classfile, 8, SEEK_CUR);<br />
++(*cur);<br />
break;<br />
default:<br />
corrupt_error();<br />
}<br />
if(seekerr)<br />
seek_error();<br />
}<br />
<br />
void error(const char *format, ...)<br />
{<br />
va_list ap;<br />
va_start(ap, format);<br />
vfprintf(stderr, format, ap);<br />
va_end(ap);<br />
exit(1);<br />
}<br />
<br />
int main(int argc, char **argv)<br />
{<br />
FILE *classfile;<br />
u_int16_t cp_count, i, this_class, classinfo_ptr;<br />
u_int8_t length;<br />
<br />
program = argv[0];<br />
<br />
if(!argv[1])<br />
error("%s: Missing input file\n", program);<br />
classfile = fopen(argv[1], "rb");<br />
if(!classfile)<br />
error("%s: Error opening %s\n", program, argv[1]);<br />
<br />
if(fseek(classfile, 8, SEEK_SET)) /* skip magic and version numbers */<br />
seek_error();<br />
cp_count = read_16(classfile);<br />
pool = calloc(cp_count, sizeof(long));<br />
if(!pool)<br />
error("%s: Out of memory for constant pool\n", program);<br />
<br />
for(i = 1; i < cp_count; ++i)<br />
skip_constant(classfile, &i);<br />
if(fseek(classfile, 2, SEEK_CUR)) /* skip access flags */<br />
seek_error();<br />
<br />
this_class = read_16(classfile);<br />
if(this_class < 1 || this_class >= cp_count)<br />
corrupt_error();<br />
if(!pool[this_class] || pool[this_class] == -1)<br />
corrupt_error();<br />
if(fseek(classfile, pool[this_class] + 1, SEEK_SET))<br />
seek_error();<br />
<br />
classinfo_ptr = read_16(classfile);<br />
if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)<br />
corrupt_error();<br />
if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)<br />
corrupt_error();<br />
if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))<br />
seek_error();<br />
<br />
length = read_16(classfile);<br />
for(i = 0; i < length; ++i)<br />
{<br />
u_int8_t x = read_8(classfile);<br />
if((x & 0x80) || !x)<br />
{<br />
if((x & 0xE0) == 0xC0)<br />
{<br />
u_int8_t y = read_8(classfile);<br />
if((y & 0xC0) == 0x80)<br />
{<br />
int c = ((x & 0x1f) << 6) + (y & 0x3f);<br />
if(c) putchar(c);<br />
else utf8_error();<br />
}<br />
else utf8_error();<br />
}<br />
else utf8_error();<br />
}<br />
else if(x == '/') putchar('.');<br />
else putchar(x);<br />
}<br />
putchar('\n');<br />
free(pool);<br />
fclose(classfile);<br />
return 0;<br />
}<br />
=Testing=<br />
Create a simple '''HelloWorld.java''' program such as the following:<br />
class HelloWorld {<br />
public static void main(String args[]) {<br />
System.out.println("Hello World!");<br />
}<br />
}<br />
Compile it as normal and make the '''.class''' file executable with the command<br />
chmod +x HelloWorld.class<br />
You should then be able to run it by simply entering:<br />
./HelloWorld.class<br />
=Notes=<br />
* Some of the material on '''binfmt_misc''' refers to it as a module but Arch builds it into the standard kernel.<br />
* The setup given here works with both the Sun JRE & openjdk6.<br />
* '''binfmt_misc''' can be used for other file types as well. For example, to be able to run DOS/Windows files without having to explicitly specify the <nowiki>wine</nowiki> program, add the following registration entry:<br />
# binfmt_misc support for DOS / Windows applications via Wine<br />
echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register<br />
[[Category:HOWTOs (English)]]</div>Alterkackerhttps://wiki.archlinux.org/index.php?title=Binfmt_misc_for_Java&diff=67217Binfmt misc for Java2009-04-20T04:47:18Z<p>Alterkacker: minor formatting fix.</p>
<hr />
<div>''This is a short tutorial on using Linux's binfmt_misc capability to make Java class and jar files easily executable from the command line.''<br />
=Introduction=<br />
''From [http://en.wikipedia.org/wiki/Binfmt_misc Wikipedia]:''<br />
<br />
"binfmt_misc is a capability of the Linux kernel which allows arbitrary executable file formats to be recognized and passed to certain user space applications, such as emulators and virtual machines."<br />
<br />
In plain language, this allows you to take a Java jar file that you would ordinarily run via a line such as<br />
java -jar /path/to/MyProgram.jar<br />
and instead run it simply with<br />
MyProgram.jar<br />
as long as it's on the PATH.<br />
<br />
The information in this article is almost entirely taken from the files '''binfmt_misc.txt''' and '''java.txt''' in the '''Documentation''' sub-directory of the Linux kernel source tree.<br />
=Setup=<br />
==Mounting binfmt_misc==<br />
For an ad-hoc mount:<br />
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc<br />
For a persistent mount via fstab add the line:<br />
none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0<br />
==Registering the file type with binfmt_misc==<br />
This is done by echoing a specially formatted line to '''/proc/sys/fs/binfmt_misc/register'''. The contents of the line is explained in the '''Documentation/binfmt_misc.txt''' file. To make the file registrations automatic at boot you can add the appropriate lines to your '''rc.local''' file, for example:<br />
# binfmt_misc support for Java applications:<br />
echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:' > /proc/sys/fs/binfmt_misc/register<br />
# binfmt_misc support for executable Jar files:<br />
echo ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:' > /proc/sys/fs/binfmt_misc/register<br />
# binfmt_misc support for Java Applets:<br />
echo ':Applet:E::html::/opt/bin/bin/appletviewer:' > /proc/sys/fs/binfmt_misc/register<br />
The first two of the above entries run Java class and jar files via <nowiki>'wrapper'</nowiki> scripts describe in the next section. The final entry runs Java applets in the usual way. You may reboot or run the file to put the registrations into effect immediately.<br />
==The wrapper scripts==<br />
===jarwrapper===<br />
#!/bin/bash<br />
# /usr/local/bin/jarwrapper - the wrapper for binfmt_misc/jar<br />
<br />
# set path to java using JAVA_HOME if available, otherwise assume it's on the PATH<br />
JAVA_PATH=${JAVA_HOME:+$JAVA_HOME/jre/bin/}java<br />
$JAVA_PATH -jar $1<br />
===javawrapper===<br />
#!/bin/bash<br />
# /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java<br />
<br />
if [ -z "$1" ]; then<br />
exec 1>&2<br />
echo Usage: $0 class-file<br />
exit 1<br />
fi<br />
<br />
CLASS=$1<br />
FQCLASS=`/usr/local/bin/javaclassname $1`<br />
FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'`<br />
FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'`<br />
<br />
# for example:<br />
# CLASS=Test.class<br />
# FQCLASS=foo.bar.Test<br />
# FQCLASSN=Test<br />
# FQCLASSP=foo/bar<br />
<br />
unset CLASSBASE<br />
<br />
declare -i LINKLEVEL=0<br />
<br />
while :; do<br />
if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then<br />
# See if this directory works straight off<br />
cd -L `dirname $CLASS`<br />
CLASSDIR=$PWD<br />
cd $OLDPWD<br />
if echo $CLASSDIR | grep -q "$FQCLASSP$"; then<br />
CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`<br />
break;<br />
fi<br />
# Try dereferencing the directory name<br />
cd -P `dirname $CLASS`<br />
CLASSDIR=$PWD<br />
cd $OLDPWD<br />
if echo $CLASSDIR | grep -q "$FQCLASSP$"; then<br />
CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`<br />
break;<br />
fi<br />
# If no other possible filename exists<br />
if [ ! -L $CLASS ]; then<br />
exec 1>&2<br />
echo $0:<br />
echo " $CLASS should be in a" \<br />
"directory tree called $FQCLASSP"<br />
exit 1<br />
fi<br />
fi<br />
if [ ! -L $CLASS ]; then break; fi<br />
# Go down one more level of symbolic links<br />
let LINKLEVEL+=1<br />
if [ $LINKLEVEL -gt 5 ]; then<br />
exec 1>&2<br />
echo $0:<br />
echo " Too many symbolic links encountered"<br />
exit 1<br />
fi<br />
CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`<br />
done<br />
<br />
if [ -z "$CLASSBASE" ]; then<br />
if [ -z "$FQCLASSP" ]; then<br />
GOODNAME=$FQCLASSN.class<br />
else<br />
GOODNAME=$FQCLASSP/$FQCLASSN.class<br />
fi<br />
exec 1>&2<br />
echo $0:<br />
echo " $FQCLASS should be in a file called $GOODNAME"<br />
exit 1<br />
fi<br />
<br />
if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then<br />
# class is not in CLASSPATH, so prepend dir of class to CLASSPATH<br />
if [ -z "${CLASSPATH}" ] ; then==<br />
export CLASSPATH=$CLASSBASE<br />
else<br />
export CLASSPATH=$CLASSBASE:$CLASSPATH<br />
fi<br />
fi<br />
<br />
shift<br />
# set path to java using JAVA_HOME if available, otherwise assume it's on the PATH<br />
JAVA_PATH=${JAVA_HOME:+$JAVA_HOME/jre/bin/}java<br />
$JAVA_PATH $FQCLASS "$@"<br />
===javaclassname===<br />
This program is used by the '''javawrapper''' script above. Compile it with the command<br />
gcc -O2 -o javaclassname javaclassname.c<br />
and move the executable to /usr/local/bin.<br />
/* javaclassname.c<br />
*<br />
* Extracts the class name from a Java class file; intended for use in a Java<br />
* wrapper of the type supported by the binfmt_misc option in the Linux kernel.<br />
*<br />
* Copyright (C) 1999 Colin J. Watson <cjw44@cam.ac.uk>.<br />
*<br />
* This program is free software; you can redistribute it and/or modify<br />
* it under the terms of the GNU General Public License as published by<br />
* the Free Software Foundation; either version 2 of the License, or<br />
* (at your option) any later version.<br />
*<br />
* This program is distributed in the hope that it will be useful,<br />
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
* GNU General Public License for more details.<br />
*<br />
* You should have received a copy of the GNU General Public License<br />
* along with this program; if not, write to the Free Software<br />
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
*/<br />
<br />
#include <stdlib.h><br />
#include <stdio.h><br />
#include <stdarg.h><br />
#include <sys/types.h><br />
<br />
/* From Sun's Java VM Specification, as tag entries in the constant pool. */<br />
<br />
#define CP_UTF8 1<br />
#define CP_INTEGER 3<br />
#define CP_FLOAT 4<br />
#define CP_LONG 5<br />
#define CP_DOUBLE 6<br />
#define CP_CLASS 7<br />
#define CP_STRING 8<br />
#define CP_FIELDREF 9<br />
#define CP_METHODREF 10<br />
#define CP_INTERFACEMETHODREF 11<br />
#define CP_NAMEANDTYPE 12<br />
<br />
/* Define some commonly used error messages */<br />
<br />
#define seek_error() error("%s: Cannot seek\n", program)<br />
#define corrupt_error() error("%s: Class file corrupt\n", program)<br />
#define eof_error() error("%s: Unexpected end of file\n", program)<br />
#define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);<br />
<br />
char *program;<br />
<br />
long *pool;<br />
<br />
u_int8_t read_8(FILE *classfile);<br />
u_int16_t read_16(FILE *classfile);<br />
void skip_constant(FILE *classfile, u_int16_t *cur);<br />
void error(const char *format, ...);<br />
int main(int argc, char **argv);<br />
<br />
/* Reads in an unsigned 8-bit integer. */<br />
u_int8_t read_8(FILE *classfile)<br />
{<br />
int b = fgetc(classfile);<br />
if(b == EOF)<br />
eof_error();<br />
return (u_int8_t)b;<br />
}<br />
<br />
/* Reads in an unsigned 16-bit integer. */<br />
u_int16_t read_16(FILE *classfile)<br />
{<br />
int b1, b2;<br />
b1 = fgetc(classfile);<br />
if(b1 == EOF)<br />
eof_error();<br />
b2 = fgetc(classfile);<br />
if(b2 == EOF)<br />
eof_error();<br />
return (u_int16_t)((b1 << 8) | b2);<br />
}<br />
<br />
/* Reads in a value from the constant pool. */<br />
void skip_constant(FILE *classfile, u_int16_t *cur)<br />
{<br />
u_int16_t len;<br />
int seekerr = 1;<br />
pool[*cur] = ftell(classfile);<br />
switch(read_8(classfile))<br />
{<br />
case CP_UTF8:<br />
len = read_16(classfile);<br />
seekerr = fseek(classfile, len, SEEK_CUR);<br />
break;<br />
case CP_CLASS:<br />
case CP_STRING:<br />
seekerr = fseek(classfile, 2, SEEK_CUR);<br />
break;<br />
case CP_INTEGER:<br />
case CP_FLOAT:<br />
case CP_FIELDREF:<br />
case CP_METHODREF:<br />
case CP_INTERFACEMETHODREF:<br />
case CP_NAMEANDTYPE:<br />
seekerr = fseek(classfile, 4, SEEK_CUR);<br />
break;<br />
case CP_LONG:<br />
case CP_DOUBLE:<br />
seekerr = fseek(classfile, 8, SEEK_CUR);<br />
++(*cur);<br />
break;<br />
default:<br />
corrupt_error();<br />
}<br />
if(seekerr)<br />
seek_error();<br />
}<br />
<br />
void error(const char *format, ...)<br />
{<br />
va_list ap;<br />
va_start(ap, format);<br />
vfprintf(stderr, format, ap);<br />
va_end(ap);<br />
exit(1);<br />
}<br />
<br />
int main(int argc, char **argv)<br />
{<br />
FILE *classfile;<br />
u_int16_t cp_count, i, this_class, classinfo_ptr;<br />
u_int8_t length;<br />
<br />
program = argv[0];<br />
<br />
if(!argv[1])<br />
error("%s: Missing input file\n", program);<br />
classfile = fopen(argv[1], "rb");<br />
if(!classfile)<br />
error("%s: Error opening %s\n", program, argv[1]);<br />
<br />
if(fseek(classfile, 8, SEEK_SET)) /* skip magic and version numbers */<br />
seek_error();<br />
cp_count = read_16(classfile);<br />
pool = calloc(cp_count, sizeof(long));<br />
if(!pool)<br />
error("%s: Out of memory for constant pool\n", program);<br />
<br />
for(i = 1; i < cp_count; ++i)<br />
skip_constant(classfile, &i);<br />
if(fseek(classfile, 2, SEEK_CUR)) /* skip access flags */<br />
seek_error();<br />
<br />
this_class = read_16(classfile);<br />
if(this_class < 1 || this_class >= cp_count)<br />
corrupt_error();<br />
if(!pool[this_class] || pool[this_class] == -1)<br />
corrupt_error();<br />
if(fseek(classfile, pool[this_class] + 1, SEEK_SET))<br />
seek_error();<br />
<br />
classinfo_ptr = read_16(classfile);<br />
if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)<br />
corrupt_error();<br />
if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)<br />
corrupt_error();<br />
if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))<br />
seek_error();<br />
<br />
length = read_16(classfile);<br />
for(i = 0; i < length; ++i)<br />
{<br />
u_int8_t x = read_8(classfile);<br />
if((x & 0x80) || !x)<br />
{<br />
if((x & 0xE0) == 0xC0)<br />
{<br />
u_int8_t y = read_8(classfile);<br />
if((y & 0xC0) == 0x80)<br />
{<br />
int c = ((x & 0x1f) << 6) + (y & 0x3f);<br />
if(c) putchar(c);<br />
else utf8_error();<br />
}<br />
else utf8_error();<br />
}<br />
else utf8_error();<br />
}<br />
else if(x == '/') putchar('.');<br />
else putchar(x);<br />
}<br />
putchar('\n');<br />
free(pool);<br />
fclose(classfile);<br />
return 0;<br />
}<br />
=Testing=<br />
Create a simple '''HelloWorld.java''' program such as the following:<br />
class HelloWorld {<br />
public static void main(String args[]) {<br />
System.out.println("Hello World!");<br />
}<br />
}<br />
Compile it as normal and make the '''.class''' file executable with the command<br />
chmod +x HelloWorld.class<br />
You should then be able to run it by simply entering:<br />
./HelloWorld.class<br />
=Notes=<br />
* Some of the material on '''binfmt_misc''' refers to it as a module but Arch builds it into the standard kernel.<br />
* The setup given here works with both the Sun JRE & openjdk6.<br />
* '''binfmt_misc''' can be used for other file types as well. For example, to be able to run DOS/Windows files without having to explicitly specify the <nowiki>wine</nowiki> program, add the following registration entry:<br />
# binfmt_misc support for DOS / Windows applications via Wine<br />
echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register<br />
[[Category:HOWTOs (English)]]</div>Alterkackerhttps://wiki.archlinux.org/index.php?title=Binfmt_misc_for_Java&diff=67216Binfmt misc for Java2009-04-20T04:43:58Z<p>Alterkacker: Initial entry.</p>
<hr />
<div>''This is a short tutorial on using Linux's binfmt_misc capability to make Java class and jar files easily executable from the command line.''<br />
=Introduction=<br />
''From [http://en.wikipedia.org/wiki/Binfmt_misc Wikipedia]:''<br />
<br />
"binfmt_misc is a capability of the Linux kernel which allows arbitrary executable file formats to be recognized and passed to certain user space applications, such as emulators and virtual machines."<br />
<br />
In plain language, this allows you to take a Java jar file that you would ordinarily run via a line such as<br />
java -jar /path/to/MyProgram.jar<br />
and instead run it simply with<br />
MyProgram.jar<br />
as long as it's on the PATH.<br />
<br />
The information in this article is almost entirely taken from the files '''binfmt_misc.txt''' and '''java.txt''' in the '''Documentation''' sub-directory of the Linux kernel source tree.<br />
=Setup=<br />
==Mounting binfmt_misc==<br />
For an ad-hoc mount:<br />
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc<br />
For a persistent mount via fstab add the line:<br />
none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0<br />
==Registering the file type with binfmt_misc==<br />
This is done by echoing a specially formatted line to '''/proc/sys/fs/binfmt_misc/register'''. The contents of the line is explained in the '''Documentation/binfmt_misc.txt''' file. To make the file registrations automatic at boot you can add the appropriate lines to your '''rc.local''' file, for example:<br />
# binfmt_misc support for Java applications:<br />
echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:' > /proc/sys/fs/binfmt_misc/register<br />
# binfmt_misc support for executable Jar files:<br />
echo ':ExecutableJAR:E::jar::/usr/local/bin/jarwrapper:' > /proc/sys/fs/binfmt_misc/register<br />
# binfmt_misc support for Java Applets:<br />
echo ':Applet:E::html::/opt/bin/bin/appletviewer:' > /proc/sys/fs/binfmt_misc/register<br />
The first two of the above entries run Java class and jar files via <nowiki>'wrapper'</nowiki> scripts describe in the next section. The final entry runs Java applets in the usual way. You may reboot or run the file to put the registrations into effect immediately.<br />
==The wrapper scripts==<br />
===jarwrapper===<br />
#!/bin/bash<br />
# /usr/local/bin/jarwrapper - the wrapper for binfmt_misc/jar<br />
<br />
# set path to java using JAVA_HOME if available, otherwise assume it's on the PATH<br />
JAVA_PATH=${JAVA_HOME:+$JAVA_HOME/jre/bin/}java<br />
$JAVA_PATH -jar $1<br />
===javawrapper===<br />
#!/bin/bash<br />
# /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java<br />
<br />
if [ -z "$1" ]; then<br />
exec 1>&2<br />
echo Usage: $0 class-file<br />
exit 1<br />
fi<br />
<br />
CLASS=$1<br />
FQCLASS=`/usr/local/bin/javaclassname $1`<br />
FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'`<br />
FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'`<br />
<br />
# for example:<br />
# CLASS=Test.class<br />
# FQCLASS=foo.bar.Test<br />
# FQCLASSN=Test<br />
# FQCLASSP=foo/bar<br />
<br />
unset CLASSBASE<br />
<br />
declare -i LINKLEVEL=0<br />
<br />
while :; do<br />
if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then<br />
# See if this directory works straight off<br />
cd -L `dirname $CLASS`<br />
CLASSDIR=$PWD<br />
cd $OLDPWD<br />
if echo $CLASSDIR | grep -q "$FQCLASSP$"; then<br />
CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`<br />
break;<br />
fi<br />
# Try dereferencing the directory name<br />
cd -P `dirname $CLASS`<br />
CLASSDIR=$PWD<br />
cd $OLDPWD<br />
if echo $CLASSDIR | grep -q "$FQCLASSP$"; then<br />
CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`<br />
break;<br />
fi<br />
# If no other possible filename exists<br />
if [ ! -L $CLASS ]; then<br />
exec 1>&2<br />
echo $0:<br />
echo " $CLASS should be in a" \<br />
"directory tree called $FQCLASSP"<br />
exit 1<br />
fi<br />
fi<br />
if [ ! -L $CLASS ]; then break; fi<br />
# Go down one more level of symbolic links<br />
let LINKLEVEL+=1<br />
if [ $LINKLEVEL -gt 5 ]; then<br />
exec 1>&2<br />
echo $0:<br />
echo " Too many symbolic links encountered"<br />
exit 1<br />
fi<br />
CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`<br />
done<br />
<br />
if [ -z "$CLASSBASE" ]; then<br />
if [ -z "$FQCLASSP" ]; then<br />
GOODNAME=$FQCLASSN.class<br />
else<br />
GOODNAME=$FQCLASSP/$FQCLASSN.class<br />
fi<br />
exec 1>&2<br />
echo $0:<br />
echo " $FQCLASS should be in a file called $GOODNAME"<br />
exit 1<br />
fi<br />
<br />
if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then<br />
# class is not in CLASSPATH, so prepend dir of class to CLASSPATH<br />
if [ -z "${CLASSPATH}" ] ; then==<br />
export CLASSPATH=$CLASSBASE<br />
else<br />
export CLASSPATH=$CLASSBASE:$CLASSPATH<br />
fi<br />
fi<br />
<br />
shift<br />
# set path to java using JAVA_HOME if available, otherwise assume it's on the PATH<br />
JAVA_PATH=${JAVA_HOME:+$JAVA_HOME/jre/bin/}java<br />
$JAVA_PATH $FQCLASS "$@"<br />
===javaclassname===<br />
This program is used by the '''javawrapper''' script above. Compile it with the command<br />
gcc -O2 -o javaclassname javaclassname.c<br />
and move the executable to /usr/local/bin.<br />
/* javaclassname.c<br />
*<br />
* Extracts the class name from a Java class file; intended for use in a Java<br />
* wrapper of the type supported by the binfmt_misc option in the Linux kernel.<br />
*<br />
* Copyright (C) 1999 Colin J. Watson <cjw44@cam.ac.uk>.<br />
*<br />
* This program is free software; you can redistribute it and/or modify<br />
* it under the terms of the GNU General Public License as published by<br />
* the Free Software Foundation; either version 2 of the License, or<br />
* (at your option) any later version.<br />
*<br />
* This program is distributed in the hope that it will be useful,<br />
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />
* GNU General Public License for more details.<br />
*<br />
* You should have received a copy of the GNU General Public License<br />
* along with this program; if not, write to the Free Software<br />
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
*/<br />
<br />
#include <stdlib.h><br />
#include <stdio.h><br />
#include <stdarg.h><br />
#include <sys/types.h><br />
<br />
/* From Sun's Java VM Specification, as tag entries in the constant pool. */<br />
<br />
#define CP_UTF8 1<br />
#define CP_INTEGER 3<br />
#define CP_FLOAT 4<br />
#define CP_LONG 5<br />
#define CP_DOUBLE 6<br />
#define CP_CLASS 7<br />
#define CP_STRING 8<br />
#define CP_FIELDREF 9<br />
#define CP_METHODREF 10<br />
#define CP_INTERFACEMETHODREF 11<br />
#define CP_NAMEANDTYPE 12<br />
<br />
/* Define some commonly used error messages */<br />
<br />
#define seek_error() error("%s: Cannot seek\n", program)<br />
#define corrupt_error() error("%s: Class file corrupt\n", program)<br />
#define eof_error() error("%s: Unexpected end of file\n", program)<br />
#define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);<br />
<br />
char *program;<br />
<br />
long *pool;<br />
<br />
u_int8_t read_8(FILE *classfile);<br />
u_int16_t read_16(FILE *classfile);<br />
void skip_constant(FILE *classfile, u_int16_t *cur);<br />
void error(const char *format, ...);<br />
int main(int argc, char **argv);<br />
<br />
/* Reads in an unsigned 8-bit integer. */<br />
u_int8_t read_8(FILE *classfile)<br />
{<br />
int b = fgetc(classfile);<br />
if(b == EOF)<br />
eof_error();<br />
return (u_int8_t)b;<br />
}<br />
<br />
/* Reads in an unsigned 16-bit integer. */<br />
u_int16_t read_16(FILE *classfile)<br />
{<br />
int b1, b2;<br />
b1 = fgetc(classfile);<br />
if(b1 == EOF)<br />
eof_error();<br />
b2 = fgetc(classfile);<br />
if(b2 == EOF)<br />
eof_error();<br />
return (u_int16_t)((b1 << 8) | b2);<br />
}<br />
<br />
/* Reads in a value from the constant pool. */<br />
void skip_constant(FILE *classfile, u_int16_t *cur)<br />
{<br />
u_int16_t len;<br />
int seekerr = 1;<br />
pool[*cur] = ftell(classfile);<br />
switch(read_8(classfile))<br />
{<br />
case CP_UTF8:<br />
len = read_16(classfile);<br />
seekerr = fseek(classfile, len, SEEK_CUR);<br />
break;<br />
case CP_CLASS:<br />
case CP_STRING:<br />
seekerr = fseek(classfile, 2, SEEK_CUR);<br />
break;<br />
case CP_INTEGER:<br />
case CP_FLOAT:<br />
case CP_FIELDREF:<br />
case CP_METHODREF:<br />
case CP_INTERFACEMETHODREF:<br />
case CP_NAMEANDTYPE:<br />
seekerr = fseek(classfile, 4, SEEK_CUR);<br />
break;<br />
case CP_LONG:<br />
case CP_DOUBLE:<br />
seekerr = fseek(classfile, 8, SEEK_CUR);<br />
++(*cur);<br />
break;<br />
default:<br />
corrupt_error();<br />
}<br />
if(seekerr)<br />
seek_error();<br />
}<br />
<br />
void error(const char *format, ...)<br />
{<br />
va_list ap;<br />
va_start(ap, format);<br />
vfprintf(stderr, format, ap);<br />
va_end(ap);<br />
exit(1);<br />
}<br />
<br />
int main(int argc, char **argv)<br />
{<br />
FILE *classfile;<br />
u_int16_t cp_count, i, this_class, classinfo_ptr;<br />
u_int8_t length;<br />
<br />
program = argv[0];<br />
<br />
if(!argv[1])<br />
error("%s: Missing input file\n", program);<br />
classfile = fopen(argv[1], "rb");<br />
if(!classfile)<br />
error("%s: Error opening %s\n", program, argv[1]);<br />
<br />
if(fseek(classfile, 8, SEEK_SET)) /* skip magic and version numbers */<br />
seek_error();<br />
cp_count = read_16(classfile);<br />
pool = calloc(cp_count, sizeof(long));<br />
if(!pool)<br />
error("%s: Out of memory for constant pool\n", program);<br />
<br />
for(i = 1; i < cp_count; ++i)<br />
skip_constant(classfile, &i);<br />
if(fseek(classfile, 2, SEEK_CUR)) /* skip access flags */<br />
seek_error();<br />
<br />
this_class = read_16(classfile);<br />
if(this_class < 1 || this_class >= cp_count)<br />
corrupt_error();<br />
if(!pool[this_class] || pool[this_class] == -1)<br />
corrupt_error();<br />
if(fseek(classfile, pool[this_class] + 1, SEEK_SET))<br />
seek_error();<br />
<br />
classinfo_ptr = read_16(classfile);<br />
if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)<br />
corrupt_error();<br />
if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)<br />
corrupt_error();<br />
if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))<br />
seek_error();<br />
<br />
length = read_16(classfile);<br />
for(i = 0; i < length; ++i)<br />
{<br />
u_int8_t x = read_8(classfile);<br />
if((x & 0x80) || !x)<br />
{<br />
if((x & 0xE0) == 0xC0)<br />
{<br />
u_int8_t y = read_8(classfile);<br />
if((y & 0xC0) == 0x80)<br />
{<br />
int c = ((x & 0x1f) << 6) + (y & 0x3f);<br />
if(c) putchar(c);<br />
else utf8_error();<br />
}<br />
else utf8_error();<br />
}<br />
else utf8_error();<br />
}<br />
else if(x == '/') putchar('.');<br />
else putchar(x);<br />
}<br />
putchar('\n');<br />
free(pool);<br />
fclose(classfile);<br />
return 0;<br />
}<br />
=Testing=<br />
Create a simple '''HelloWorld.java''' program such as the following:<br />
class HelloWorld {<br />
public static void main(String args[]) {<br />
System.out.println("Hello World!");<br />
}<br />
}<br />
Compile it as normal and make the '''.class''' file executable with the command<br />
chmod +x HelloWorld.class<br />
You should then be able to run it by simply entering:<br />
./HelloWorld.class<br />
=Notes=<br />
* Some of the material on '''binfmt_misc''' refers to it as a module but Arch builds it into the standard kernel.<br />
* The setup given here works with both the Sun JRE & openjdk6.<br />
* '''binfmt_misc''' can be used for other file types as well. For example, to be able to run DOS/Windows files without having to explicitly specify the <nowiki>wine</nowiki> program, add the following registration entry:<br />
# binfmt_misc support for DOS / Windows applications via Wine<br />
echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register<br />
[[Category:HOWTOs (English)]]</div>Alterkackerhttps://wiki.archlinux.org/index.php?title=ArchWiki:Sandbox&diff=67210ArchWiki:Sandbox2009-04-20T01:14:14Z<p>Alterkacker: added code block</p>
<hr />
<div>{{i18n_links_start}}<br />
{{i18n_entry|Deutsch|Sandkasten}}<br />
{{i18n_entry|English|Sandbox}}<br />
{{i18n_entry|简体中文|沙盘}}<br />
{{i18n_entry|Hebrew|ארגז חול}}<br />
{{i18n_entry|Português do Brasil|CaixadeAreia}}<br />
{{i18n_entry|Türkçe|Oyun Sahası}}<br />
{{i18n_entry|Русский|Песочница}}<br />
{{i18n_links_end}}<br />
<br />
'''Welcome to the ArchWiki. Feel free to train your Wiki editing skills on this page.'''<br />
<br />
Some pointers to learn the right syntax:<br />
* http://en.wikipedia.org/wiki/Wikipedia:Cheatsheet<br />
* http://en.wikipedia.org/wiki/Wikipedia:How_to_edit_a_page<br />
* http://meta.wikimedia.org/wiki/Category:Documentation<br />
* http://en.wikipedia.org/wiki/Help:Table<br />
<br />
<br><hr> <!-- Your stuff goes below this line, okay? --><br />
<br />
{{sn|Side note}}<br />
<br />
BLAH TEST<br />
<br />
{{Keypress|Return}}<br />
<br />
[[Wikipedia:Arch Linux]]<br />
<br />
# pacman -S foo bar<br />
<br />
{{Command|name=Command Name|output=Command Output}}<br />
<br />
{{File|name=File Name|content=File Content}}<br />
<br />
{{Kernel|content=Kernel Content}}<br />
<br />
{{Note|Note text}}<br />
<br />
{{Tip|Tip text}}<br />
<br />
{{Warning|Warning text}}<br />
<br />
{{Codeline|pacman --sync --refresh --sysupgrade}}<br />
<br />
{{Filename|/etc/rc.local}}<br />
<br />
{{Progressbar|13}}<br />
<br />
{| border="1"<br />
| A || B<br />
|- <br />
| C || D <br />
|}<br />
<br />
Q: Isn't is possible to add remote image files to wiki?<br />
<br />
A: No. The setting is disabled. Contact a wiki admin to upload images to the wiki, which can then be used as such:<br />
<br />
[[Image:Tango-two-arrows.png]]<br />
<br />
=Top Level Heading=<br />
==And Here's the Code==<br />
line1<br />
line2<br />
line3<br />
<br />
[[Category:Help]]</div>Alterkacker