chiark / gitweb /
Sort of works ...
[jarrg-ian.git] / pctb-preload-wrap.c
1 /**/
2
3 #define _GNU_SOURCE
4 #include <dlfcn.h>
5 #include <stdio.h>
6 #include <unistd.h>
7
8 #define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1)
9 #define STDERRSTR_STRING(m) write(2,m,strlen(m))
10
11 static anyfn_type *find_any(const char *name) {
12   static const char *dlerr;
13   anyfn_type *kv;
14
15   kv= dlsym(RTLD_NEXT,name); if (kv) return kv;
16   dlerr= dlerror(); if (!dlerr) dlerr= "dlsym() failed for no reason";
17   STDERRSTR_CONST("pctb-preload-wrap: error finding original version of ");
18   STDERRSTR_STRING(name);
19   STDERRSTR_CONST(": ");
20   STDERRSTR_STRING(dlerr);
21   STDERRSTR_STRING("\n");
22   errno= ENOSYS;
23   return 0;
24 }
25
26 typedef int
27 execvefn_type(const char *path, char *const argv[], char *const envp[]);
28
29 static execvefn_type find_execve, *old_execve= find_execve;
30
31 static int find_execve(const char *path,
32                        char *const argv[], char *const envp[]) {
33   anyfn_type *anyfn;
34   anyfn= find_any("execve"); if (!anyfn) return -1;
35   old_execve= (execvefn_type*)anyfn;
36   return old_execve(path, argv, envp);
37 }
38
39 int execve(const char *opath, char *const oargv[], char *const oenvp[]) {
40   int oargc;
41   for (oargc=0; oargv[oargc]; oargc++);
42   xassert(oargc);
43   if (strcmp(oargv[oargc-1], "com.threerings.yohoho.client.YoApp"))
44     old_execve(opath, oargv, oenvp);
45
46   /* Remove ourselves from LD_PRELOAD */
47   int ipreloadenv=-1;
48   const char ldpreload[]= "LD_PRELOAD=";
49   for (oenvc=0; oenvp[oenvc]; oenvc++) {
50     if (memcmp(oenvp[oenvc], ldpreload, sizeof(ldpreload)-1)) continue;
51     xassert(ipreloadenv==-1);
52     ipreloadenv= oenvc;
53   }
54   xassert(ipreloadenv>=0);
55   xassert(!strchr(':',oenvp[ipreloadenv]));
56   
57
58   int nargc= oargc+2;
59   char **nargv= xmalloc(sizeof(*nargv) * (nargc+1));
60
61   /* Add argument for accessibility assistive tech. */
62   int iargc= oargc-1;
63   memcpy(nargv, oargv, iargc);
64   nargv[iargc++]= "-Djavax.accessibility.assistive_technologies="
65     "com.tedpearson.ypp.market.MarketUploader";
66
67   /* Calculate and add argument for ext dirs containing our jars */
68   const char *nextdir;
69   xassert((nextdir= getenv("JPCTB_EXTDIR")));
70   int nextdirlen= strlen(nextdir);
71
72   const char path2extdir_rm[]= "/bin/java";
73   int opathlen= strlen(opath);
74   int njvmextdirbaselen= opathlen-sizeof(path2extdir_rm)-1);
75   xassert(opathlen >= sizeof(path2extdir_rm));
76   xassert(!strcmp(path2extdir_rm, opath+njvmextdirbaselen);
77
78   const char path2extdir_pfx[]= "-Djava.ext.dirs=";
79   const char path2extdir_sfx[]= "/lib/ext";
80
81 #define STRS(STR,DL)                                            \
82       STR( path2extdir_pfx, sizeof(path2extdir_pfx)-1 ) DL      \
83       STR( nextdir,         nextdirlen                ) DL      \
84       STR( ":",             1                         ) DL      \
85       STR( opath,           njvmextdirbaselen         ) DL      \
86       STR( path2extdir_sfx, sizeof(path2extdir_sfx)-1 ) DL      \
87       STR( "",              1                         )
88
89 #define STR_LEN(str,len) (len)
90   char *nextdirarg= xmalloc(STRS(STR_LEN, +));
91   char *p= nextdirarg;
92
93 #define STR_ADD(str,len) \
94   memcpy(p,(str),(len)); p += (len);
95   STRS(STR_ADD, ;);
96
97   nargv[iargc++]= nextdirarg;
98
99   /* Remaining argument: the class */
100   nargv[iargc++]= oargv[oargc-1];
101
102  
103
104
105
106     if (arg
107 }