# HG changeset patch # User Andre Heinecke # Date 1397576827 -7200 # Node ID 5eb7ee4ee819a90e9d30be603e8e84417ab92ae1 # Parent 124f08a8553230765622e6a30f905f320a5b6d4c Look up executable name based on /proc/self/exe diff -r 124f08a85532 -r 5eb7ee4ee819 cinst/nssstore_linux.c --- a/cinst/nssstore_linux.c Tue Apr 15 17:46:16 2014 +0200 +++ b/cinst/nssstore_linux.c Tue Apr 15 17:47:07 2014 +0200 @@ -11,11 +11,57 @@ #include #include #include +#include #include "nssstore.h" #include "logging.h" #include "strhelp.h" +#define NSS_PROCESS_NAME "mozilla" + +/**@brief get the current path of the executable + * + * Looks up the current executables directory. The caller + * has to free the return value. + * + * The returned value includes the last / + * + * @returns the absolute directory of the currently executed executable or NULL + */ +char * +get_exe_dir() +{ + char *retval = NULL, + *p = NULL, + buf[PATH_MAX]; + ssize_t ret; + size_t path_len = 0; + + ret = readlink ("/proc/self/exe", buf, PATH_MAX); + if (ret <= 0) + { + ERRORPRINTF ("readlink failed\n"); + return NULL; + } + + buf[ret] = '\0'; + + /* cut off the filename */ + p = strrchr (buf, '/'); + if (p == NULL) + { + ERRORPRINTF ("No filename found.\n"); + return NULL; + } + *(p + 1) = '\0'; + + path_len = strlen (buf); + retval = xmalloc (path_len + 1); + strncpy (retval, buf, path_len); + + return retval; +} + /**@brief Start the process to install / remove * * This forks the process and executes the NSS installation @@ -35,9 +81,11 @@ { int pipe_fd[2]; pid_t pid = 0; - char *argv[] = {"mozilla", NULL}, - *envp[2]; - size_t homedir_len = 0; + char *argv[2] = {NULL, NULL}, + *envp[2] = {NULL, NULL}, + *inst_dir = NULL; + size_t homedir_len = 0, + exe_path_len = 0; int ret = -1, i = 0; FILE *stream = NULL; @@ -64,7 +112,25 @@ return -1; } - DEBUGPRINTF ("Home: %s \n", envp[0]); + /* Set up the file name of the installer process */ + inst_dir = get_exe_dir(); + if (inst_dir == NULL) + { + ERRORPRINTF ("Failed to find installation directory.\n"); + xfree (envp[0]); + return -1; + } + + exe_path_len = strlen(inst_dir) + strlen(NSS_PROCESS_NAME); + argv[0] = xmalloc (exe_path_len + 1); + + ret = snprintf(argv[0], exe_path_len + 1, "%s%s", inst_dir, NSS_PROCESS_NAME); + if (ret < 0 || (size_t) ret != exe_path_len) + { + ERRORPRINTF ("Error setting executable variable.\n"); + xfree (argv[0]); + return -1; + } if (pipe (pipe_fd)) { @@ -92,7 +158,7 @@ dup2 (pipe_fd[0], 0); close (pipe_fd[0]); /* TODO find path based on current executable */ - execve ("mozilla", argv, envp); + execve (argv[0], argv, envp); exit (127); } @@ -129,9 +195,10 @@ if (stream) { fclose (stream); } + xfree (argv[0]); xfree (envp[0]); - close(pipe_fd[0]); - close(pipe_fd[1]); + close (pipe_fd[0]); + close (pipe_fd[1]); if (success) { @@ -171,7 +238,6 @@ ERRORPRINTF ("Waitpid failed.\n"); return -1; } - DEBUGPRINTF ("Child returned status: %i\n", WEXITSTATUS(status)); return 0; }