|
|
|
@ -14,10 +14,11 @@
|
|
|
|
|
#define __BINRELOC_C__
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_BINRELOC
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#endif /* ENABLE_BINRELOC */
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
@ -29,14 +30,13 @@ extern "C" {
|
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @internal
|
|
|
|
|
* Find the canonical filename of the executable. Returns the filename
|
|
|
|
|
* (which must be freed) or NULL on error. If the parameter 'error' is
|
|
|
|
|
* not NULL, the error code will be stored there, if an error occured.
|
|
|
|
|
*/
|
|
|
|
|
static char *
|
|
|
|
|
_br_find_exe (BrInitError *error)
|
|
|
|
|
_br_find_exe(BrInitError *error)
|
|
|
|
|
{
|
|
|
|
|
#ifndef ENABLE_BINRELOC
|
|
|
|
|
if (error)
|
|
|
|
@ -175,14 +175,14 @@ _br_find_exe (BrInitError *error)
|
|
|
|
|
* Returns a filename which must be freed, or NULL on error.
|
|
|
|
|
*/
|
|
|
|
|
static char *
|
|
|
|
|
_br_find_exe_for_symbol (const void *symbol, BrInitError *error)
|
|
|
|
|
_br_find_exe_for_symbol(const void *symbol, BrInitError *error)
|
|
|
|
|
{
|
|
|
|
|
#ifndef ENABLE_BINRELOC
|
|
|
|
|
if (error)
|
|
|
|
|
*error = BR_INIT_ERROR_DISABLED;
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
#else
|
|
|
|
|
#define SIZE PATH_MAX + 100
|
|
|
|
|
#define SIZE PATH_MAX + 100
|
|
|
|
|
FILE *f;
|
|
|
|
|
size_t address_string_len;
|
|
|
|
|
char *address_string, line[SIZE], *found;
|
|
|
|
@ -279,8 +279,8 @@ _br_find_exe_for_symbol (const void *symbol, BrInitError *error)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef BINRELOC_RUNNING_DOXYGEN
|
|
|
|
|
#undef NULL
|
|
|
|
|
#define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
|
|
|
|
|
#undef NULL
|
|
|
|
|
#define NULL ((void *) 0) /* typecasted as char* for C++ type safeness */
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static char *exe = (char *) NULL;
|
|
|
|
@ -301,9 +301,9 @@ static char *exe = (char *) NULL;
|
|
|
|
|
* @returns 1 on success, 0 if BinReloc failed to initialize.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
br_init (BrInitError *error)
|
|
|
|
|
br_init(BrInitError *error)
|
|
|
|
|
{
|
|
|
|
|
exe = _br_find_exe (error);
|
|
|
|
|
exe = _br_find_exe(error);
|
|
|
|
|
return exe != NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -323,9 +323,9 @@ br_init (BrInitError *error)
|
|
|
|
|
* @returns 1 on success, 0 if a filename cannot be found.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
br_init_lib (BrInitError *error)
|
|
|
|
|
br_init_lib(BrInitError *error)
|
|
|
|
|
{
|
|
|
|
|
exe = _br_find_exe_for_symbol ((const void *) "", error);
|
|
|
|
|
exe = _br_find_exe_for_symbol((const void *) "", error);
|
|
|
|
|
return exe != NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -340,16 +340,17 @@ br_init_lib (BrInitError *error)
|
|
|
|
|
* NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_exe (const char *default_exe)
|
|
|
|
|
br_find_exe(const char *default_exe)
|
|
|
|
|
{
|
|
|
|
|
if (exe == (char *) NULL) {
|
|
|
|
|
if (exe == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc is not initialized. */
|
|
|
|
|
if (default_exe != (const char *) NULL)
|
|
|
|
|
return strdup (default_exe);
|
|
|
|
|
return strdup(default_exe);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
return strdup (exe);
|
|
|
|
|
return strdup(exe);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -368,17 +369,18 @@ br_find_exe (const char *default_exe)
|
|
|
|
|
* returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_exe_dir (const char *default_dir)
|
|
|
|
|
br_find_exe_dir(const char *default_dir)
|
|
|
|
|
{
|
|
|
|
|
if (exe == NULL) {
|
|
|
|
|
if (exe == NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_dir != NULL)
|
|
|
|
|
return strdup (default_dir);
|
|
|
|
|
return strdup(default_dir);
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return br_dirname (exe);
|
|
|
|
|
return br_dirname(exe);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -396,21 +398,22 @@ br_find_exe_dir (const char *default_dir)
|
|
|
|
|
* will be returned. If default_prefix is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_prefix (const char *default_prefix)
|
|
|
|
|
br_find_prefix(const char *default_prefix)
|
|
|
|
|
{
|
|
|
|
|
char *dir1, *dir2;
|
|
|
|
|
|
|
|
|
|
if (exe == (char *) NULL) {
|
|
|
|
|
if (exe == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_prefix != (const char *) NULL)
|
|
|
|
|
return strdup (default_prefix);
|
|
|
|
|
return strdup(default_prefix);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir1 = br_dirname (exe);
|
|
|
|
|
dir2 = br_dirname (dir1);
|
|
|
|
|
free (dir1);
|
|
|
|
|
dir1 = br_dirname(exe);
|
|
|
|
|
dir2 = br_dirname(dir1);
|
|
|
|
|
free(dir1);
|
|
|
|
|
return dir2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -429,21 +432,22 @@ br_find_prefix (const char *default_prefix)
|
|
|
|
|
* be returned. If default_bin_dir is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_bin_dir (const char *default_bin_dir)
|
|
|
|
|
br_find_bin_dir(const char *default_bin_dir)
|
|
|
|
|
{
|
|
|
|
|
char *prefix, *dir;
|
|
|
|
|
|
|
|
|
|
prefix = br_find_prefix ((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL) {
|
|
|
|
|
prefix = br_find_prefix((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_bin_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_bin_dir);
|
|
|
|
|
return strdup(default_bin_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (prefix, "bin");
|
|
|
|
|
free (prefix);
|
|
|
|
|
dir = br_build_path(prefix, "bin");
|
|
|
|
|
free(prefix);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -462,21 +466,22 @@ br_find_bin_dir (const char *default_bin_dir)
|
|
|
|
|
* be returned. If default_bin_dir is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_sbin_dir (const char *default_sbin_dir)
|
|
|
|
|
br_find_sbin_dir(const char *default_sbin_dir)
|
|
|
|
|
{
|
|
|
|
|
char *prefix, *dir;
|
|
|
|
|
|
|
|
|
|
prefix = br_find_prefix ((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL) {
|
|
|
|
|
prefix = br_find_prefix((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_sbin_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_sbin_dir);
|
|
|
|
|
return strdup(default_sbin_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (prefix, "sbin");
|
|
|
|
|
free (prefix);
|
|
|
|
|
dir = br_build_path(prefix, "sbin");
|
|
|
|
|
free(prefix);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -496,21 +501,22 @@ br_find_sbin_dir (const char *default_sbin_dir)
|
|
|
|
|
* returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_data_dir (const char *default_data_dir)
|
|
|
|
|
br_find_data_dir(const char *default_data_dir)
|
|
|
|
|
{
|
|
|
|
|
char *prefix, *dir;
|
|
|
|
|
|
|
|
|
|
prefix = br_find_prefix ((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL) {
|
|
|
|
|
prefix = br_find_prefix((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_data_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_data_dir);
|
|
|
|
|
return strdup(default_data_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (prefix, "share");
|
|
|
|
|
free (prefix);
|
|
|
|
|
dir = br_build_path(prefix, "share");
|
|
|
|
|
free(prefix);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -529,21 +535,22 @@ br_find_data_dir (const char *default_data_dir)
|
|
|
|
|
* If default_locale_dir is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_locale_dir (const char *default_locale_dir)
|
|
|
|
|
br_find_locale_dir(const char *default_locale_dir)
|
|
|
|
|
{
|
|
|
|
|
char *data_dir, *dir;
|
|
|
|
|
|
|
|
|
|
data_dir = br_find_data_dir ((const char *) NULL);
|
|
|
|
|
if (data_dir == (char *) NULL) {
|
|
|
|
|
data_dir = br_find_data_dir((const char *) NULL);
|
|
|
|
|
if (data_dir == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_locale_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_locale_dir);
|
|
|
|
|
return strdup(default_locale_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (data_dir, "locale");
|
|
|
|
|
free (data_dir);
|
|
|
|
|
dir = br_build_path(data_dir, "locale");
|
|
|
|
|
free(data_dir);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -562,21 +569,22 @@ br_find_locale_dir (const char *default_locale_dir)
|
|
|
|
|
* If default_lib_dir is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_lib_dir (const char *default_lib_dir)
|
|
|
|
|
br_find_lib_dir(const char *default_lib_dir)
|
|
|
|
|
{
|
|
|
|
|
char *prefix, *dir;
|
|
|
|
|
|
|
|
|
|
prefix = br_find_prefix ((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL) {
|
|
|
|
|
prefix = br_find_prefix((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_lib_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_lib_dir);
|
|
|
|
|
return strdup(default_lib_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (prefix, "lib");
|
|
|
|
|
free (prefix);
|
|
|
|
|
dir = br_build_path(prefix, "lib");
|
|
|
|
|
free(prefix);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -595,21 +603,22 @@ br_find_lib_dir (const char *default_lib_dir)
|
|
|
|
|
* If default_libexec_dir is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_libexec_dir (const char *default_libexec_dir)
|
|
|
|
|
br_find_libexec_dir(const char *default_libexec_dir)
|
|
|
|
|
{
|
|
|
|
|
char *prefix, *dir;
|
|
|
|
|
|
|
|
|
|
prefix = br_find_prefix ((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL) {
|
|
|
|
|
prefix = br_find_prefix((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_libexec_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_libexec_dir);
|
|
|
|
|
return strdup(default_libexec_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (prefix, "libexec");
|
|
|
|
|
free (prefix);
|
|
|
|
|
dir = br_build_path(prefix, "libexec");
|
|
|
|
|
free(prefix);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -628,21 +637,22 @@ br_find_libexec_dir (const char *default_libexec_dir)
|
|
|
|
|
* If default_etc_dir is NULL, then NULL will be returned.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_find_etc_dir (const char *default_etc_dir)
|
|
|
|
|
br_find_etc_dir(const char *default_etc_dir)
|
|
|
|
|
{
|
|
|
|
|
char *prefix, *dir;
|
|
|
|
|
|
|
|
|
|
prefix = br_find_prefix ((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL) {
|
|
|
|
|
prefix = br_find_prefix((const char *) NULL);
|
|
|
|
|
if (prefix == (char *) NULL)
|
|
|
|
|
{
|
|
|
|
|
/* BinReloc not initialized. */
|
|
|
|
|
if (default_etc_dir != (const char *) NULL)
|
|
|
|
|
return strdup (default_etc_dir);
|
|
|
|
|
return strdup(default_etc_dir);
|
|
|
|
|
else
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dir = br_build_path (prefix, "etc");
|
|
|
|
|
free (prefix);
|
|
|
|
|
dir = br_build_path(prefix, "etc");
|
|
|
|
|
free(prefix);
|
|
|
|
|
return dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -658,7 +668,7 @@ br_find_etc_dir (const char *default_etc_dir)
|
|
|
|
|
* @returns A newly-allocated string. This string should be freed when no longer needed.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_strcat (const char *str1, const char *str2)
|
|
|
|
|
br_strcat(const char *str1, const char *str2)
|
|
|
|
|
{
|
|
|
|
|
char *result;
|
|
|
|
|
size_t len1, len2;
|
|
|
|
@ -668,12 +678,12 @@ br_strcat (const char *str1, const char *str2)
|
|
|
|
|
if (str2 == NULL)
|
|
|
|
|
str2 = "";
|
|
|
|
|
|
|
|
|
|
len1 = strlen (str1);
|
|
|
|
|
len2 = strlen (str2);
|
|
|
|
|
len1 = strlen(str1);
|
|
|
|
|
len2 = strlen(str2);
|
|
|
|
|
|
|
|
|
|
result = (char *) malloc (len1 + len2 + 1);
|
|
|
|
|
memcpy (result, str1, len1);
|
|
|
|
|
memcpy (result + len1, str2, len2);
|
|
|
|
|
result = (char *) malloc(len1 + len2 + 1);
|
|
|
|
|
memcpy(result, str1, len1);
|
|
|
|
|
memcpy(result + len1, str2, len2);
|
|
|
|
|
result[len1 + len2] = '\0';
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
@ -681,29 +691,30 @@ br_strcat (const char *str1, const char *str2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
|
br_build_path (const char *dir, const char *file)
|
|
|
|
|
br_build_path(const char *dir, const char *file)
|
|
|
|
|
{
|
|
|
|
|
char *dir2, *result;
|
|
|
|
|
size_t len;
|
|
|
|
|
int must_free = 0;
|
|
|
|
|
|
|
|
|
|
len = strlen (dir);
|
|
|
|
|
if (len > 0 && dir[len - 1] != '/') {
|
|
|
|
|
dir2 = br_strcat (dir, "/");
|
|
|
|
|
len = strlen(dir);
|
|
|
|
|
if (len > 0 && dir[len - 1] != '/')
|
|
|
|
|
{
|
|
|
|
|
dir2 = br_strcat(dir, "/");
|
|
|
|
|
must_free = 1;
|
|
|
|
|
} else
|
|
|
|
|
dir2 = (char *) dir;
|
|
|
|
|
|
|
|
|
|
result = br_strcat (dir2, file);
|
|
|
|
|
result = br_strcat(dir2, file);
|
|
|
|
|
if (must_free)
|
|
|
|
|
free (dir2);
|
|
|
|
|
free(dir2);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Emulates glibc's strndup() */
|
|
|
|
|
static char *
|
|
|
|
|
br_strndup (const char *str, size_t size)
|
|
|
|
|
br_strndup(const char *str, size_t size)
|
|
|
|
|
{
|
|
|
|
|
char *result = (char *) NULL;
|
|
|
|
|
size_t len;
|
|
|
|
@ -711,14 +722,14 @@ br_strndup (const char *str, size_t size)
|
|
|
|
|
if (str == (const char *) NULL)
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
|
|
|
|
|
len = strlen (str);
|
|
|
|
|
len = strlen(str);
|
|
|
|
|
if (len == 0)
|
|
|
|
|
return strdup ("");
|
|
|
|
|
return strdup("");
|
|
|
|
|
if (size > len)
|
|
|
|
|
size = len;
|
|
|
|
|
|
|
|
|
|
result = (char *) malloc (len + 1);
|
|
|
|
|
memcpy (result, str, size);
|
|
|
|
|
result = (char *) malloc(len + 1);
|
|
|
|
|
memcpy(result, str, size);
|
|
|
|
|
result[size] = '\0';
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -737,23 +748,24 @@ br_strndup (const char *str, size_t size)
|
|
|
|
|
* @returns A directory name. This string should be freed when no longer needed.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
|
|
|
|
br_dirname (const char *path)
|
|
|
|
|
br_dirname(const char *path)
|
|
|
|
|
{
|
|
|
|
|
char *end, *result;
|
|
|
|
|
|
|
|
|
|
if (path == (const char *) NULL)
|
|
|
|
|
return (char *) NULL;
|
|
|
|
|
|
|
|
|
|
end = strrchr (path, '/');
|
|
|
|
|
end = strrchr(path, '/');
|
|
|
|
|
if (end == (const char *) NULL)
|
|
|
|
|
return strdup (".");
|
|
|
|
|
return strdup(".");
|
|
|
|
|
|
|
|
|
|
while (end > path && *end == '/')
|
|
|
|
|
end--;
|
|
|
|
|
result = br_strndup (path, end - path + 1);
|
|
|
|
|
if (result[0] == 0) {
|
|
|
|
|
free (result);
|
|
|
|
|
return strdup ("/");
|
|
|
|
|
result = br_strndup(path, end - path + 1);
|
|
|
|
|
if (result[0] == 0)
|
|
|
|
|
{
|
|
|
|
|
free(result);
|
|
|
|
|
return strdup("/");
|
|
|
|
|
} else
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|