chiark / gitweb /
Before do munging in sh
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 1 Nov 2009 19:12:50 +0000 (19:12 +0000)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 1 Nov 2009 19:12:50 +0000 (19:12 +0000)
pctb-preload-wrap.c [new file with mode: 0644]

diff --git a/pctb-preload-wrap.c b/pctb-preload-wrap.c
new file mode 100644 (file)
index 0000000..a547c01
--- /dev/null
@@ -0,0 +1,107 @@
+/**/
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1)
+#define STDERRSTR_STRING(m) write(2,m,strlen(m))
+
+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("pctb-preload-wrap: error finding original version of ");
+  STDERRSTR_STRING(name);
+  STDERRSTR_CONST(": ");
+  STDERRSTR_STRING(dlerr);
+  STDERRSTR_STRING("\n");
+  errno= ENOSYS;
+  return 0;
+}
+
+typedef int
+execvefn_type(const char *path, char *const argv[], char *const envp[]);
+
+static execvefn_type find_execve, *old_execve= find_execve;
+
+static int find_execve(const char *path,
+                      char *const argv[], char *const envp[]) {
+  anyfn_type *anyfn;
+  anyfn= find_any("execve"); if (!anyfn) return -1;
+  old_execve= (execvefn_type*)anyfn;
+  return old_execve(path, argv, envp);
+}
+
+int execve(const char *opath, char *const oargv[], char *const oenvp[]) {
+  int oargc;
+  for (oargc=0; oargv[oargc]; oargc++);
+  xassert(oargc);
+  if (strcmp(oargv[oargc-1], "com.threerings.yohoho.client.YoApp"))
+    old_execve(opath, oargv, oenvp);
+
+  /* Remove ourselves from LD_PRELOAD */
+  int ipreloadenv=-1;
+  const char ldpreload[]= "LD_PRELOAD=";
+  for (oenvc=0; oenvp[oenvc]; oenvc++) {
+    if (memcmp(oenvp[oenvc], ldpreload, sizeof(ldpreload)-1)) continue;
+    xassert(ipreloadenv==-1);
+    ipreloadenv= oenvc;
+  }
+  xassert(ipreloadenv>=0);
+  xassert(!strchr(':',oenvp[ipreloadenv]));
+  
+
+  int nargc= oargc+2;
+  char **nargv= xmalloc(sizeof(*nargv) * (nargc+1));
+
+  /* Add argument for accessibility assistive tech. */
+  int iargc= oargc-1;
+  memcpy(nargv, oargv, iargc);
+  nargv[iargc++]= "-Djavax.accessibility.assistive_technologies="
+    "com.tedpearson.ypp.market.MarketUploader";
+
+  /* Calculate and add argument for ext dirs containing our jars */
+  const char *nextdir;
+  xassert((nextdir= getenv("JPCTB_EXTDIR")));
+  int nextdirlen= strlen(nextdir);
+
+  const char path2extdir_rm[]= "/bin/java";
+  int opathlen= strlen(opath);
+  int njvmextdirbaselen= opathlen-sizeof(path2extdir_rm)-1);
+  xassert(opathlen >= sizeof(path2extdir_rm));
+  xassert(!strcmp(path2extdir_rm, opath+njvmextdirbaselen);
+
+  const char path2extdir_pfx[]= "-Djava.ext.dirs=";
+  const char path2extdir_sfx[]= "/lib/ext";
+
+#define STRS(STR,DL)                                           \
+      STR( path2extdir_pfx, sizeof(path2extdir_pfx)-1 )        DL      \
+      STR( nextdir,         nextdirlen                )        DL      \
+      STR( ":",             1                         )        DL      \
+      STR( opath,           njvmextdirbaselen         )        DL      \
+      STR( path2extdir_sfx, sizeof(path2extdir_sfx)-1 )        DL      \
+      STR( "",              1                         )
+
+#define STR_LEN(str,len) (len)
+  char *nextdirarg= xmalloc(STRS(STR_LEN, +));
+  char *p= nextdirarg;
+
+#define STR_ADD(str,len) \
+  memcpy(p,(str),(len)); p += (len);
+  STRS(STR_ADD, ;);
+
+  nargv[iargc++]= nextdirarg;
+
+  /* Remaining argument: the class */
+  nargv[iargc++]= oargv[oargc-1];
+
+
+
+
+    if (arg
+}