diff --git a/envtrace b/envtrace index 72a3584..be8a25d 100755 --- a/envtrace +++ b/envtrace @@ -7,8 +7,6 @@ export ENVTRACE_LOGFILE=${ENVTRACE_ROOT}/env.trace echo "Writing ENVTRACE to: ${ENVTRACE_LOGFILE}" -printenv > ${ENVTRACE_LOGFILE} - exec "$@" exit 1 diff --git a/envtrace-helper.c b/envtrace-helper.c index 297b6f3..88f147f 100644 --- a/envtrace-helper.c +++ b/envtrace-helper.c @@ -1,4 +1,6 @@ #define _GNU_SOURCE +#include +#include #include #include #include @@ -6,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -19,123 +22,142 @@ static int (*real_setenv) ( const char *name,const char *value,int overwrite ) = static int (*real_unsetenv) ( const char *name ) = 0; static pid_t (*real_fork) ( ) = 0; static int (*real_clone) ( int (*fn)(void *),void *child_stack,int flags,void *arg,... ) = 0; - -char * getenv( const char *name ) +static int (*real_open) ( const char *pathname,int flags,... ) = 0; +static int (*real_openat) ( int dirfd, const char *pathname, int flags,... ) = 0; +static int (*real_creat) ( const char *pathname,mode_t mode ) = 0; +static FILE * (*real_fopen) ( const char *path,const char *mode ) = 0; +static FILE * (*real_freopen) ( const char *path,const char *mode,FILE *stream ) = 0; +static int (*real_execv) ( const char *path,char *const argv[] ) = 0; +static int (*real_execl) ( const char *path,const char *arg0,... ) = 0; +static int (*real_execve) ( const char *path,char *const argv[],char *const envp[] ) = 0; +static int (*real_execle) ( const char *path,const char *arg0,... ) = 0; +static int (*real_execvp) ( const char *file,char *const argv[] ) = 0; +static int (*real_execlp) ( const char *file,const char *arg0,... ) = 0; +static int (*real_execvpe) ( const char *file,char *const argv[],char *const envp[] ) = 0; + +void logfile_check() { - if(!real_getenv) { - real_getenv = dlsym(RTLD_NEXT,"getenv"); - if(!real_getenv) { - fprintf(stderr,"envtrace-helper: couldn't find original getenv()\n"); - exit(1); - } - } - if(!logfile_name) { - logfile_name = real_getenv("ENVTRACE_LOGFILE"); + if(!logfile_name) { + if(!real_getenv) { + real_getenv = dlsym(RTLD_NEXT,"getenv"); + if(!real_getenv) { + fprintf(stderr,"envtrace-helper: couldn't find original getenv().\n"); + exit(1); + } + } + logfile_name = real_getenv("ENVTRACE_LOGFILE"); if(!logfile_name) { fprintf(stderr,"envtrace-helper: ENVTRACE_LOGFILE is not set.\n"); exit(1); } } + if(!logfile) { + if(!real_fopen) { + real_fopen = dlsym(RTLD_NEXT,"fopen"); + if(!real_fopen) { + fprintf(stderr,"envtrace-helper: couldn't find original fopen().\n"); + exit(1); + } + } + logfile = real_fopen(logfile_name,"a"); if(!logfile) { - logfile = fopen(logfile_name,"a"); - if(!logfile) { - fprintf(stderr,"envtrace-helper: couldn't open %s for logging: %s\n",(char *)logfile,strerror(errno)); - exit(1); - } + fprintf(stderr,"envtrace-helper: couldn't open %s for logging: %s\n",(char *)logfile,strerror(errno)); + exit(1); + } } +} + +char * getenv( const char *name ) +{ + if(!real_getenv) { + real_getenv = dlsym(RTLD_NEXT,"getenv"); + if(!real_getenv) { + fprintf(stderr,"envtrace-helper: couldn't find original getenv().\n"); + exit(1); + } + } + + logfile_check(); char *result = real_getenv(name); pid_t pid = getpid(); pid_t ppid = getppid(); - struct timeval timestamp; - gettimeofday(×tamp,NULL); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); if(result) { - fprintf(logfile,"%ld: %ld %ld %s %s HIT %s\n",(long)timestamp.tv_sec,(long)ppid,(long)pid,program_invocation_name,name,result); + fprintf(logfile,"%s@%s %ld.%ld: GETENV %ld %ld %s %s HIT %s\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,name,result); } else { - fprintf(logfile,"%ld: %ld %ld %s %s MISS\n",(long)timestamp.tv_sec,(long)ppid,(long)pid,program_invocation_name,name); + fprintf(logfile,"%s@%s %ld.%ld: GETENV %ld %ld %s %s MISS\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,name); } fflush(logfile); return result; } -int setenv(const char *name, const char *value, int overwrite) +int setenv( const char *name,const char *value,int overwrite ) { if(!real_setenv) { real_setenv = dlsym(RTLD_NEXT,"setenv"); if(!real_setenv) { - fprintf(stderr,"envtrace-helper: couldn't find original setenv()\n"); + fprintf(stderr,"envtrace-helper: couldn't find original setenv().\n"); exit(1); } } - if(!logfile_name) { - logfile_name = getenv("ENVTRACE_LOGFILE"); - if(!logfile_name) { - fprintf(stderr,"envtrace-helper: ENVTRACE_LOGFILE is not set.\n"); - exit(1); - } - } - - if(!logfile) { - logfile = fopen(logfile_name,"a"); - if(!logfile) { - fprintf(stderr,"envtrace-helper: couldn't open %s for logging: %s\n",(char *)logfile,strerror(errno)); - exit(1); - } - } + logfile_check(); + const char *prev_val = getenv(name); int result = real_setenv(name,value,overwrite); pid_t pid = getpid(); pid_t ppid = getppid(); - struct timeval timestamp; - gettimeofday(×tamp,NULL); - - fprintf(logfile,"%ld: SETENV %ld %ld %s %s %s %d\n",(long)timestamp.tv_sec,(long)ppid,(long)pid,program_invocation_name,name,value,result); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: SETENV %ld %ld %s %s %s %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,name,prev_val,value,result); fflush(logfile); return result; } -int unsetenv(const char *name) +int unsetenv( const char *name ) { if(!real_unsetenv) { real_unsetenv = dlsym(RTLD_NEXT,"unsetenv"); if(!real_unsetenv) { - fprintf(stderr,"envtrace-helper: couldn't find original unsetenv()\n"); - exit(1); - } - } - - if(!logfile_name) { - logfile_name = getenv("ENVTRACE_LOGFILE"); - if(!logfile_name) { - fprintf(stderr,"envtrace-helper: ENVTRACE_LOGFILE is not set.\n"); + fprintf(stderr,"envtrace-helper: couldn't find original unsetenv().\n"); exit(1); } } - if(!logfile) { - logfile = fopen(logfile_name,"a"); - if(!logfile) { - fprintf(stderr,"envtrace-helper: couldn't open %s for logging: %s\n",(char *)logfile,strerror(errno)); - exit(1); - } - } + logfile_check(); + const char *prev_val = getenv(name); int result = real_unsetenv(name); pid_t pid = getpid(); pid_t ppid = getppid(); - struct timeval timestamp; - gettimeofday(×tamp,NULL); - fprintf(logfile,"%ld: UNSET %ld %ld %s %s %d\n",(long)timestamp.tv_sec,(long)ppid,(long)pid,program_invocation_name,name,result); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: UNSET %ld %ld %s %s %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,name,prev_val,result); fflush(logfile); return result; @@ -147,33 +169,24 @@ pid_t fork() if(!real_fork) { real_fork = dlsym(RTLD_NEXT,"fork"); if(!real_fork) { - fprintf(stderr,"envtrace-helper: couldn't find original fork()\n"); + fprintf(stderr,"envtrace-helper: couldn't find original fork().\n"); exit(1); } } - if(!logfile_name) { - logfile_name = getenv("ENVTRACE_LOGFILE"); - if(!logfile_name) { - fprintf(stderr,"envtrace-helper: ENVTRACE_LOGFILE is not set.\n"); - exit(1); - } - } + logfile_check(); - if(!logfile) { - logfile = fopen(logfile_name,"a"); - if(!logfile) { - fprintf(stderr,"envtrace-helper: couldn't open %s for logging: %s\n",(char *)logfile,strerror(errno)); - exit(1); - } - } - pid_t result = real_fork(); pid_t pid = getpid(); pid_t ppid = getppid(); - struct timeval timestamp; - gettimeofday(×tamp,NULL); - fprintf(logfile,"%ld: FORK %ld %ld %s %"PRId64"\n",(long)timestamp.tv_sec,(long)ppid,(long)pid,program_invocation_name,(int64_t) result); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(1024); + size_t hostsize = 1024; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: FORK %ld %ld %s %"PRId64"\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,(int64_t) result); fflush(logfile); return result; @@ -184,34 +197,468 @@ int clone( int (*fn)(void *),void *child_stack,int flags,void *arg,.../* pid_t * if(!real_clone) { real_clone = dlsym(RTLD_NEXT,"clone"); if(!real_clone) { - fprintf(stderr,"envtrace-helper: couldn't find original clone()\n"); + fprintf(stderr,"envtrace-helper: couldn't find original clone().\n"); exit(1); } } - if(!logfile_name) { - logfile_name = getenv("ENVTRACE_LOGFILE"); - if(!logfile_name) { - fprintf(stderr,"envtrace-helper: ENVTRACE_LOGFILE is not set.\n"); + logfile_check(); + + int result = real_clone(fn,child_stack,flags,arg); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: CLONE %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int open( const char *pathname,int flags,... ) +{ + if(!real_open) { + real_open = dlsym(RTLD_NEXT,"open"); + if(!real_open) { + fprintf(stderr,"envtrace-helper: couldn't find original open().\n"); exit(1); } } - if(!logfile) { - logfile = fopen(logfile_name,"a"); - if(!logfile) { - fprintf(stderr,"envtrace-helper: couldn't open %s for logging: %s\n",(char *)logfile,strerror(errno)); - exit(1); - } + logfile_check(); + + va_list ap; + int mode; + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + + int result = real_open(pathname,flags,mode); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: OPEN %ld %ld %s %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,pathname,result); + fflush(logfile); + + return result; +} + +int openat ( int dirfd, const char *pathname, int flags,... ) +{ + if(!real_openat) { + real_openat = dlsym(RTLD_NEXT,"openat"); + if(!real_openat) { + fprintf(stderr,"envtrace-helper: couldn't find original openat().\n"); + exit(1); + } } - - int result = real_clone(fn,child_stack,flags,arg); + + logfile_check(); + + va_list ap; + int mode; + va_start(ap, flags); + mode = va_arg(ap, int); + va_end(ap); + + int result = real_openat(dirfd,pathname,flags,mode); pid_t pid = getpid(); pid_t ppid = getppid(); - struct timeval timestamp; - gettimeofday(×tamp,NULL); - fprintf(logfile,"%ld: CLONE %ld %ld %s %d\n",(long)timestamp.tv_sec,(long)ppid,(long)pid,program_invocation_name,result); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: OPENAT %ld %ld %s %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,pathname,result); fflush(logfile); return result; } + +int creat( const char *pathname,mode_t mode ) +{ + if(!real_creat) { + real_creat = dlsym(RTLD_NEXT,"creat"); + if(!real_creat) { + fprintf(stderr,"envtrace-helper: couldn't find original creat().\n"); + exit(1); + } + } + + logfile_check(); + + int result = real_creat(pathname,mode); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: CREAT %ld %ld %s %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,pathname,result); + fflush(logfile); + + return result; +} + +FILE *fopen( const char *path,const char *mode ) +{ + if(!real_fopen) { + real_fopen = dlsym(RTLD_NEXT,"fopen"); + if(!real_fopen) { + fprintf(stderr,"envtrace-helper: couldn't find original fopen().\n"); + exit(1); + } + } + + logfile_check(); + + FILE *result = real_fopen(path,mode); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: FOPEN %ld %ld %s %s %p\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,path,result); + fflush(logfile); + + return result; +} + +FILE *freopen ( const char *path,const char *mode,FILE *stream ) +{ + if(!real_freopen) { + real_freopen = dlsym(RTLD_NEXT,"freopen"); + if(!real_freopen) { + fprintf(stderr,"envtrace-helper: couldn't find original freopen().\n"); + exit(1); + } + } + + logfile_check(); + + FILE *result = real_freopen(path,mode,stream); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: FREOPEN %ld %ld %s %s %p\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,path,result); + fflush(logfile); + + return result; +} + +int execv ( const char *path,char *const argv[] ) +{ + if(!real_execv) { + real_execv = dlsym(RTLD_NEXT,"execv"); + if(!real_execv) { + fprintf(stderr,"envtrace-helper: couldn't find original execv().\n"); + exit(1); + } + } + + logfile_check(); + + int result = real_execv(path,argv); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECV %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int execl ( const char *path,const char *arg0,... ) +{ + if(!real_execl) { + real_execl = dlsym(RTLD_NEXT,"execl"); + if(!real_execl) { + fprintf(stderr,"envtrace-helper: couldn't find original execl().\n"); + exit(1); + } + } + + logfile_check(); + + ptrdiff_t argc; + va_list ap; + va_start (ap, arg0); + for (argc = 1; va_arg (ap, const char *); argc++) + { + if (argc == INT_MAX) + { + va_end (ap); + errno = E2BIG; + return -1; + } + } + va_end (ap); + + ptrdiff_t i; + char *argv[argc + 1]; + va_start (ap, arg0); + argv[0] = (char *) arg0; + for (i = 1; i <= argc; i++) + { + argv[i] = va_arg (ap, char *); + } + va_end (ap); + + if(!real_execv) { + real_execv = dlsym(RTLD_NEXT,"execv"); + if(!real_execv) { + fprintf(stderr,"envtrace-helper: couldn't find original execv() for executing execl().\n"); + exit(1); + } + } + int result = real_execv(path,argv); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECL %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int execve ( const char *path,char *const argv[],char *const envp[] ) +{ + if(!real_execve) { + real_execve = dlsym(RTLD_NEXT,"execve"); + if(!real_execve) { + fprintf(stderr,"envtrace-helper: couldn't find original execve().\n"); + exit(1); + } + } + + logfile_check(); + + int result = real_execve(path,argv,envp); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECVE %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int execle ( const char *path,const char *arg0,... ) +{ + if(!real_execle) { + real_execle = dlsym(RTLD_NEXT,"execle"); + if(!real_execle) { + fprintf(stderr,"envtrace-helper: couldn't find original execle().\n"); + exit(1); + } + } + + logfile_check(); + + ptrdiff_t argc; + va_list ap; + va_start (ap, arg0); + for (argc = 1; va_arg (ap, const char *); argc++) + { + if (argc == INT_MAX) + { + va_end (ap); + errno = E2BIG; + return -1; + } + } + va_end (ap); + + ptrdiff_t i; + char *argv[argc + 1]; + char **envp; + va_start (ap, arg0); + argv[0] = (char *) arg0; + for (i = 1; i <= argc; i++) + { + argv[i] = va_arg (ap, char *); + } + envp = va_arg (ap, char **); + va_end (ap); + + if(!real_execve) { + real_execve = dlsym(RTLD_NEXT,"execve"); + if(!real_execve) { + fprintf(stderr,"envtrace-helper: couldn't find original execve() for executing execle().\n"); + exit(1); + } + } + int result = real_execve(path,argv,envp); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECLE %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int execvp ( const char *file,char *const argv[] ) +{ + if(!real_execvp) { + real_execvp = dlsym(RTLD_NEXT,"execvp"); + if(!real_execvp) { + fprintf(stderr,"envtrace-helper: couldn't find original execvp().\n"); + exit(1); + } + } + + logfile_check(); + + int result = real_execvp(file,argv); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECVP %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int execlp ( const char *file,const char *arg0,... ) +{ + if(!real_execlp) { + real_execlp = dlsym(RTLD_NEXT,"execlp"); + if(!real_execlp) { + fprintf(stderr,"envtrace-helper: couldn't find original execlp().\n"); + exit(1); + } + } + + logfile_check(); + + ptrdiff_t argc; + va_list ap; + va_start (ap, arg0); + for (argc = 1; va_arg (ap, const char *); argc++) + { + if (argc == INT_MAX) + { + va_end (ap); + errno = E2BIG; + return -1; + } + } + va_end (ap); + + ptrdiff_t i; + char *argv[argc + 1]; + va_start (ap, arg0); + argv[0] = (char *) arg0; + for (i = 1; i <= argc; i++) + { + argv[i] = va_arg (ap, char *); + } + va_end (ap); + + if(!real_execvp) { + real_execvp = dlsym(RTLD_NEXT,"execvp"); + if(!real_execvp) { + fprintf(stderr,"envtrace-helper: couldn't find original execvp() for executing execlp().\n"); + exit(1); + } + } + int result = real_execvp(file,argv); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECLP %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +} + +int execvpe ( const char *file,char *const argv[],char *const envp[] ) +{ + if(!real_execvpe) { + real_execvpe = dlsym(RTLD_NEXT,"execvpe"); + if(!real_execvpe) { + fprintf(stderr,"envtrace-helper: couldn't find original execvpe().\n"); + exit(1); + } + } + + logfile_check(); + + int result = real_execvpe(file,argv,envp); + pid_t pid = getpid(); + pid_t ppid = getppid(); + struct timespec timestamp; + clock_gettime(CLOCK_REALTIME,×tamp); + char *user = real_getenv("USER"); + char *hostname = malloc(sizeof(INT_MAX)); + size_t hostsize = INT_MAX; + gethostname(hostname,hostsize); + + fprintf(logfile,"%s@%s %ld.%ld: EXECVPE %ld %ld %s %d\n",user,hostname,(long)timestamp.tv_sec,timestamp.tv_nsec,(long)ppid,(long)pid,program_invocation_name,result); + fflush(logfile); + + return result; +}