From f990674d59428070dc501681c7fafd6a2e7e07d7 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 1 Nov 2009 22:43:26 +0000 Subject: [PATCH] new wrapper script actually works ian@liberator:~$ ~/Pctb-java/linkfarmer/jpctb ~/Pctb-java/installer-unpacked yohoho/yohoho jpctb: jpctb tree: "/home/ian/Pctb-java/linkfarmer" yohoho: "yohoho/yohoho" java: "/home/ian/yohoho/java" PCTB jars: "/home/ian/Pctb-java/installer-unpacked" jpctb tmpdir: "/home/ian/Pctb-java/linkfarmer/tmp" --- .gitignore | 1 + Makefile | 26 ------ jpctb | 117 +++++++++++++++++++++++++-- jwrap-script-jpctb | 61 -------------- libjwrap.c | 194 --------------------------------------------- 5 files changed, 110 insertions(+), 289 deletions(-) delete mode 100644 Makefile delete mode 100755 jwrap-script-jpctb delete mode 100644 libjwrap.c diff --git a/.gitignore b/.gitignore index b1e012f..a393599 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.o *.so *.so.* +tmp diff --git a/Makefile b/Makefile deleted file mode 100644 index 0b52505..0000000 --- a/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -OPTIMISE= -O2 -LDFLAGS= -g -LIBS= -ldl -lc -CFLAGS= -g $(OPTIMISE) \ - -Wall -Wwrite-strings -Wpointer-arith -Wimplicit \ - -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes -CPPFLAGS= - -MAJOR=1 -MINOR=0 -LIBCANON= libjwrap.so.$(MAJOR) -LIBTARGET= $(LIBCANON).$(MINOR) - -TARGETS= $(LIBTARGET) - -all: $(TARGETS) - - -$(LIBTARGET): libjwrap.o - ld -shared -soname $(LIBCANON) -o $@ $< $(LIBS) - -libjwrap.o: libjwrap.c - $(CC) -D_REENTRANT $(CFLAGS) $(CPPFLAGS) -c -o $@ -fPIC $< - -clean: - rm -f *.o $(TARGETS) *~ diff --git a/jpctb b/jpctb index c50b43b..a2cb243 100755 --- a/jpctb +++ b/jpctb @@ -4,15 +4,116 @@ usage: .../jpctb /path/to/dir/with/PCTB*.jar /path/to/yohoho/yohoho [...] END } -jpctb_base="$0" -jpctb_base="${jpctb_base%/*}" +fail () { + echo >&2 "jpctb: $*" + exit 127 +} + +if [ $# -lt 2 ]; then usage; fail 'bad usage'; exit 127; fi + +srcjardir="$1"; shift +yohoho="$1"; shift + +#---------- find ourselves ---------- + +jpctbdir="$0" +jpctbdir="${jpctbdir%/*}" + +case "$jpctbdir" in +/*) ;; +*) jpctbdir="$PWD/$jpctbdir" ;; +esac + +#---------- find YPP client and the Java installation it uses ---------- + +yppdir="${yohoho%/*}" + +if [ -x "$yppdir/java/bin/java" ]; then + javadir="$yppdir/java" +elif [ x"$JAVA_HOME" != x ] && [ -x "$JAVA_HOME/bin/java" ]; then + javadir="$JAVA_HOME" +else + fail "could not find java runtime system" +fi + +case "$javadir" in +/*) ;; +*) javadir="$PWD/$javadir" ;; +esac + +jtmp="$jpctbdir/tmp" +linkfarm="$jtmp/linkfarm" +extdir="$jtmp/ext" + +#---------- confirm for the user which paths we're using ---------- + +cat <&2; exit 127; fi +lndir -silent "$javadir" "$linkfarm" + +#---------- edit the linkfarm to have our jvm wrapper ---------- + +wrapper="$linkfarm"/jre/bin/java +rm -- "$wrapper" + +export JPCTB_EXTDIR="$extdir" +export JPCTB_JRE="$javadir/jre" + +cat <<'END' >"$wrapper" +#!/bin/bash + set -e$JPCTB_JWRAP_X + + log () { + lh=`date +'%Y/%m/%d %H:%M:%S jpctb'` + printf >&2 "%s: %s |\f\n" "$lh" "$*" + } + + log "invoked as $*" + +#echo >&2 "$djava-wrap +#exec 4>>/home/ian/u +#date >&4 +#exec 4>&- + + yppclass=com.threerings.yohoho.client.YoApp + atclass=com.tedpearson.ypp.market.MarketUploader + + args=( "$@" ) + nargs=${#args[*]} + lastarg="${args[$(( $nargs - 1 ))]}" + + fail () { echo >&2 "jpctb-java: $*"; exit 127; } + + if [ x"$lastarg" = x"$yppclass" ]; then + + [ x"$JPCTB_EXTDIR" != x ] || fail 'JPCTB_EXTDIR not set' + + set -e$JPCTB_JWRAP_X -- \ + -Djavax.accessibility.assistive_technologies=$atclass \ + -Djava.ext.dirs="$JPCTB_EXTDIR:$JPCTB_JRE/lib/ext" \ + "$@" + fi + + real="$JPCTB_JRE/bin/java" + log "running $real $*" + exec "$real" "$@" +END -export JWRAP_EXTDIR="$1"; shift -export JWRAP_SCRIPT="$jpctb_base/jwrap-script-jpctb" +chmod +x -- "$wrapper" -if [ x"$LD_PRELOAD" != x ]; then LD_PRELOAD="$LD_PRELOAD:"; fi -export LD_PRELOAD="${LD_PRELOAD}$jpctb_base/libjwrap.so.1.0" +#---------- now run it ---------- -exec "$@" +exec "$yohoho" -Djava.home="$linkfarm/jre" diff --git a/jwrap-script-jpctb b/jwrap-script-jpctb deleted file mode 100755 index 72aa83e..0000000 --- a/jwrap-script-jpctb +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -set -e$JWRAP_SCRIPT_X - -#exec 4>&2 -#exec 2>>/home/ian/u -#date >&2 - -unwire () { - ldp="$LD_PRELOAD:" - ldp2='' - - while [ "x$ldp" != x ]; do - this="${ldp%%:*}" - ldp="${ldp#*:}" - case "$this" in - *libjwrap*.so.*) ;; - *) ldp2="$ldp2$this:" ;; - esac - done - - if [ "x$ldp2" != x ]; then - LD_PRELOAD="${ldp2%:}" - else - unset LD_PRELOAD - fi - - unset JWRAP_SCRIPT -} - -true jwrap-script-pctb: "$@" - -path="$1"; shift -arg0="$1"; shift - -args=( "$@" ) -nargs=${#args[*]} -lastarg="${args[$(( $nargs - 1 ))]}" - -fail () { - echo >&2 "jwrap-script: $*" - exit 127 -} - -if [ x"$lastarg" = x"com.threerings.yohoho.client.YoApp" ]; then - case "$path" in - */bin/java) ;; - *) fail "unexpected path format $path" ;; - esac - [ x"$JWRAP_EXTDIR" != x ] || fail 'JWRAP_EXTDIR not set' - extdirs="$JWRAP_EXTDIR:${path%/bin/java}/lib/ext" - - set -e$JWRAP_SCRIPT_X -- \ - -Djavax.accessibility.assistive_technologies=com.tedpearson.ypp.market.MarketUploader \ - -Djava.ext.dirs="$extdirs" \ - "$@" - - unwire -fi - -exec -a "$arg0" /dev/jwrap/bypass "$path" "$@" -#2>&4 diff --git a/libjwrap.c b/libjwrap.c deleted file mode 100644 index 23ee7d6..0000000 --- a/libjwrap.c +++ /dev/null @@ -1,194 +0,0 @@ -/**/ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -#define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1) -#define STDERRSTR_STRING(m) write(2,m,strlen(m)) - -#define QUIS "libjwrap" - -typedef void anyfn_type(void); - -static anyfn_type *find_any(const char *name) { - static const char *dlerr; - anyfn_type *kv; - - kv= dlsym(RTLD_NEXT,name); if (kv) return kv; - dlerr= dlerror(); if (!dlerr) dlerr= "dlsym() failed for no reason"; - STDERRSTR_CONST(QUIS ": error finding original version of "); - STDERRSTR_STRING(name); - STDERRSTR_CONST(": "); - STDERRSTR_STRING(dlerr); - STDERRSTR_CONST("\n"); - errno= ENOSYS; - return 0; -} - - -#define REIMPLEMENTWRAP(FN, ARGS_DECL, ARGS_USE) \ - \ - typedef int FN##_type ARGS_DECL; \ - \ - static FN##_type find_##FN, *old_##FN= find_##FN; \ - \ - static int find_##FN ARGS_DECL { \ - anyfn_type *anyfn; \ - anyfn= find_any(# FN); if (!anyfn) return -1; \ - old_##FN= (FN##_type*)anyfn; \ - return old_##FN ARGS_USE; \ - } \ - \ - int FN ARGS_DECL - - - -static const char javatail[]= "/bin/java"; - -REIMPLEMENTWRAP(execve, - (const char *path, char *const oargv[], char *const envp[]), - (path, oargv, envp)) { - int oargc; - for (oargc=0; oargv[oargc]; oargc++); - - if (!strcmp(path,"/dev/jwrap/bypass")) { - //STDERRSTR_CONST(QUIS ": bypass\n"); - int nargc= oargc-1; - char **nargv= malloc(sizeof(*nargv) * nargc); if (!nargv) return -1; - nargv[0]= oargv[0]; - memcpy(nargv+1, oargv+2, sizeof(*nargv) * nargc-1); - return old_execve(oargv[1], nargv, envp); - } - - int pathlen= strlen(path); - if (!oargc || - pathlen < (sizeof(javatail)-1) || - strcmp(javatail, path + pathlen-(sizeof(javatail)-1))) { - //STDERRSTR_CONST(QUIS ": non-java\n"); - return old_execve(path, oargv, envp); - } - - //STDERRSTR_CONST(QUIS ": ours\n"); - - struct stat stab; - if (stat(path,&stab)) return -1; - - int nargc= oargc+2; - char **nargv= malloc(sizeof(*nargv) * nargc); if (!nargv) return -1; - - const char *jwrap_script= getenv("JWRAP_SCRIPT"); - if (!jwrap_script) { - STDERRSTR_CONST(QUIS ": no JWRAP_SCRIPT specified!\n"); - errno= ENOENT; - return -1; - } - - nargv[0]= (char*)jwrap_script; - nargv[1]= (char*)path; - memcpy(nargv+2, oargv, sizeof(*nargv) * (oargc+1)); - - old_execve(nargv[0], nargv, envp); - int e= errno; - - const char *errstr= strerror(e); - STDERRSTR_CONST(QUIS ": failed to execute "); - STDERRSTR_STRING(jwrap_script); - STDERRSTR_CONST(": "); - STDERRSTR_STRING(errstr); - STDERRSTR_CONST("\n"); - - errno= e; - return -1; -} - -int execv(const char *path, char *const argv[]) { - return execve(path, argv, environ); -} - - -static int execvep(const char *path, char *const argv[], char *const envp[]) { - /* How tiresome. - * libc binds strongly to its own execve. - * That means we need to reimplement exec*p. - * (Also for some mysterious reason there is no standard execvep - * and no standard execlep) - */ - if (strchr(path,'/')) return execve(path,argv,envp); - - int pathlen= strlen(path); - int buflen= 0; - char *buf= 0; - - const char *searchpath= getenv("PATH"); - for (;;) { - const char *colon= strchr(searchpath,':'); - int entrylen= colon ? colon - searchpath : strlen(searchpath); - const char *try; - if (entrylen) { - try= path; - } else { - int trylen= entrylen + 1 + pathlen + 1; - if (trylen > buflen) { - free(buf); - buf= malloc(trylen); - if (!buf) return -1; - buflen= trylen; - } - memcpy(buf, searchpath, entrylen); - buf[entrylen]= '/'; - strcpy(buf+entrylen+1, path); - try= buf; - } - execve(try, argv, envp); - if (errno != ENOENT) - return -1; - } - errno= ENOENT; - return -1; -} - - -static int execl_corev(int e, int p, - const char *path, const char *arg0, va_list al) { - char *arg; - va_list countal; - - va_copy(countal,al); - int argc=1; - while ((arg= va_arg(countal, char*))) - argc++; - va_end(countal); - - char **argv= malloc(sizeof(*argv) * (argc+1)); - argc=0; - argv[argc++]= (char*)arg0; - while ((arg= va_arg(al, char*))) - argv[argc++]= arg; - argv[argc]= 0; - - char **envp= e ? va_arg(al, char**) : environ; - - if (p) return execvep(path, argv, envp); - else return execve(path, argv, envp); -} - - -#define REIMPLEMENTLCOREV(FN,E,P) \ - int FN(const char *path, const char *arg, ...) { \ - va_list al; \ - va_start(al,arg); \ - execl_corev(E,P,path,arg,al); \ - va_end(al); \ - return -1; \ - } - -REIMPLEMENTLCOREV( execl, 0,0 ) -REIMPLEMENTLCOREV( execle, 1,0 ) -REIMPLEMENTLCOREV( execlp, 0,1 ) -- 2.30.2