All pastes #1497035 Raw Edit

Stuff

public c v1 · immutable
#1497035 ·published 2009-07-16 13:49 UTC
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");        }    }}