rendered paste body#define _GNU_SOURCE#include <assert.h>#include <dlfcn.h>#include <stdlib.h>#include <string.h>#include <unistd.h>typedef int (*execveProto)(const char* filename, char * const argv[], char * const envp[]);static int isEnabled;static char **programList;static const char *tbPath;static execveProto realExecve;static __attribute__((constructor)) void construct();static void debug(const char *msg){ if (isatty(1)) write(1, msg, strlen(msg));}int execve(const char *filename, char *const argv[], char *const envp[]){ if (!isEnabled) realExecve(filename, argv, envp); const char *execname = strrchr(filename, '/'); if (!execname) execname = filename; else ++execname; //debug("** trying to execute program: "); //debug(execname); //debug("\n"); int i = 0; for ( ; programList[i]; ++i) if (strcmp(execname, programList[i]) == 0) { // disable ourselves char *const *p = envp; for (; *p; ++p) if (strncmp(*p, "EN_TB=", 6) == 0) (*p)[6] = '\0'; // replace with teambuilder: //debug("** replacing executable with teambuilder\n"); realExecve(tbPath, argv, envp); } // not found, execute as is realExecve(filename, argv, envp);}static const char *findInPath(const char *progname){ const char *PATH = getenv("PATH"); if (!PATH) return 0; // can't find anything in $PATH if there isn't one char *path = malloc(strlen(PATH) + strlen(progname) + 2); const char *begin = PATH; while (begin && *begin) { while (*begin == ':') ++begin; size_t len = strcspn(begin, ":"); memcpy(path, begin, len); path[len] = '/'; path[len + 1] = '\0'; strcat(path, progname); if (access(path, X_OK) == 0) return path; begin += len; } free(path); return 0; // failed to find anything}void construct(){ isEnabled = 0; realExecve = dlsym(RTLD_NEXT, "execve"); assert(realExecve); // first of all, find teambuilder const char *TEAMBUILDER = getenv("TEAMBUILDER"); const char *EN_TB = getenv("EN_TB"); if ((TEAMBUILDER && strcmp(TEAMBUILDER, "0") == 0) || !EN_TB || *EN_TB == '\0') { //debug("** teambuilder is disabled\n"); return; } else { // find teambuilder tbPath = getenv("TEAMBUILDER_EXECUTABLE"); if (!tbPath) tbPath = findInPath("tb"); if (!tbPath) { isEnabled = 0; debug("** cannot find teambuilder, disabling\n"); } else { isEnabled = 1; //debug("** enabled, using teambuilder: "); //debug(tbPath); //debug("\n** programs to consider: "); // we're in business // build the list of programs we'll use char *en_tb = strdup(EN_TB); int alloc = 4, count = 0; programList = malloc(alloc * sizeof(char *)); programList[count] = NULL; while (*en_tb) { if (alloc == count + 1) { // get more space alloc *= 2; programList = realloc(programList, alloc * sizeof(char *)); } assert(programList); // append the current entry programList[count++] = en_tb; programList[count] = NULL; // nul-terminate the current entry while (*en_tb != ':' && *en_tb) ++en_tb; if (*en_tb) *en_tb++ = '\0'; //debug(programList[count - 1]); //debug(" "); } //debug("\n"); } }}