/**/ #define _GNU_SOURCE #include #include #include #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); } static const char javatail[]= "/bin/java"; int execve(const char *path, char *const argv[], char *const envp[]) { int pathlen= strlen(path); if (pathlen < (sizeof(path2extdir_rm)-1) || strcmp(javatail, path + pathlen-(sizeof(path2extdir_rm)-1))) old_execve(opath, oargv, oenvp); int oargc; xassert(opathlen >= for (oargc=0; oargv[oargc]; oargc++); xassert(oargc); if (strcmp(oargv[oargc-1], "com.threerings.yohoho.client.YoApp")) /* 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); int njvmextdirbaselen= opathlen-sizeof(path2extdir_rm)-1); 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 }