33 #ifndef __BINRELOC_C__ 34 #define __BINRELOC_C__ 42 #ifdef ENABLE_BINRELOC 43 #include <sys/types.h> 47 #ifdef MAC_INTEGRATION 48 #include <gtkmacintegration/gtkosxapplication.h> 49 #elif GNC_PLATFORM_OSX 50 #include <mach-o/dyld.h> 60 #include "gncla-dir.h" 70 _br_find_exe (Gnc_GbrInitError *error)
72 #ifndef ENABLE_BINRELOC 74 *error = GNC_GBR_INIT_ERROR_DISABLED;
76 #elif defined G_OS_WIN32 81 gchar *prefix = g_win32_get_package_installation_directory_of_module (NULL);
82 gchar *result = g_build_filename (prefix,
"bin",
"gnucash.exe", NULL);
86 *error = GNC_GBR_INIT_WIN32_NO_EXE_DIR;
89 if (!g_file_test (result, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE))
92 result = g_build_filename (prefix,
"gnucash.exe", NULL);
93 if (!g_file_test (result,
94 G_FILE_TEST_EXISTS | G_FILE_TEST_IS_EXECUTABLE))
99 *error = GNC_GBR_INIT_WIN32_NO_EXE_DIR;
105 char path[PATH_MAX + 1], path2[PATH_MAX + 1];
107 size_t buf_size = PATH_MAX + 1;
110 #ifdef MAC_INTEGRATION 111 result = gtkosx_application_get_executable_path();
112 strncpy (path2, result, buf_size - 1);
114 g_print (
"Application Path %s\n", path2);
115 #elif defined GNC_PLATFORM_OSX 117 uint32_t size2 = buf_size;
118 if (_NSGetExecutablePath (path2, &size2) != 0)
122 *error = GNC_GBR_INIT_ERROR_NOMEM;
126 strncpy (path2,
"/proc/self/exe", buf_size - 1);
130 if (realpath (path2, path) != NULL)
132 return g_strdup (path);
138 buf_size = PATH_MAX + 128;
139 line = (
char *) g_try_malloc (buf_size);
144 *error = GNC_GBR_INIT_ERROR_NOMEM;
148 f = fopen (
"/proc/self/maps",
"r");
153 *error = GNC_GBR_INIT_ERROR_OPEN_MAPS;
158 result = fgets (line, (
int) buf_size, f);
164 *error = GNC_GBR_INIT_ERROR_READ_MAPS;
169 buf_size = strlen (line);
176 *error = GNC_GBR_INIT_ERROR_INVALID_MAPS;
179 if (line[buf_size - 1] == 10)
180 line[buf_size - 1] = 0;
183 result = strchr (line,
'/');
186 if (strstr (line,
" r-xp ") == NULL || result == NULL)
191 *error = GNC_GBR_INIT_ERROR_INVALID_MAPS;
195 result = g_strdup (result);
204 static gchar *exe = NULL;
206 static void set_gerror (GError **error, Gnc_GbrInitError errcode);
209 void gnc_gbr_set_exe (
const gchar* default_exe)
215 if (default_exe != NULL)
216 exe = g_strdup(default_exe);
236 gnc_gbr_init (GError **error)
238 Gnc_GbrInitError errcode = 0;
241 exe = _br_find_exe (&errcode);
248 set_gerror (error, errcode);
255 set_gerror (GError **error, Gnc_GbrInitError errcode)
257 gchar *error_message;
264 case GNC_GBR_INIT_ERROR_NOMEM:
265 error_message =
"Cannot allocate memory.";
267 case GNC_GBR_INIT_ERROR_OPEN_MAPS:
268 error_message =
"Unable to open /proc/self/maps for reading.";
270 case GNC_GBR_INIT_ERROR_READ_MAPS:
271 error_message =
"Unable to read from /proc/self/maps.";
273 case GNC_GBR_INIT_ERROR_INVALID_MAPS:
274 error_message =
"The file format of /proc/self/maps is invalid.";
276 case GNC_GBR_INIT_ERROR_DISABLED:
277 error_message =
"Binary relocation support is disabled.";
279 case GNC_GBR_INIT_ERROR_MAC_NOT_BUNDLE:
280 error_message =
"BinReloc determined that gnucash is not running from a bundle";
282 case GNC_GBR_INIT_ERROR_MAC_NOT_APP_BUNDLE:
283 error_message =
"Binreloc determined that the bundle is not an app bundle";
285 case GNC_GBR_INIT_WIN32_NO_EXE_DIR:
286 error_message =
"Binreloc was unable to determine the location of gnucash.exe.";
289 error_message =
"Unknown error.";
292 g_set_error (error, g_quark_from_static_string (
"GBinReloc"),
293 errcode,
"%s", error_message);
307 gnc_gbr_find_exe (
const gchar *default_exe)
312 if (default_exe != NULL)
313 return g_strdup (default_exe);
317 return g_strdup (exe);
336 gnc_gbr_find_exe_dir (
const gchar *default_dir)
341 if (default_dir != NULL)
342 return g_strdup (default_dir);
347 return g_path_get_dirname (exe);
366 static inline gchar *
367 get_mac_bundle_prefix()
369 #if defined ENABLE_BINRELOC && defined MAC_INTEGRATION 370 gchar *
id = gtkosx_application_get_bundle_id ();
371 gchar *path = gtkosx_application_get_resource_path ();
372 gchar *basename = g_path_get_basename (path);
379 if (
id == NULL || g_getenv (
"GNC_UNINSTALLED"))
389 if (g_strcmp0 (
"bin", basename) == 0)
404 get_builddir_prefix()
406 if (g_getenv (
"GNC_UNINSTALLED"))
407 return g_strdup (g_getenv (
"GNC_BUILDDIR"));
412 gnc_gbr_find_prefix (
const gchar *default_prefix)
415 if ((dir2 = get_builddir_prefix()) || (dir2 = get_mac_bundle_prefix()))
420 if (default_prefix != NULL)
421 return g_strdup (default_prefix);
425 dir1 = g_path_get_dirname (exe);
426 dir2 = g_path_get_dirname (dir1);
447 find_component_directory (
const gchar *default_dir,
const gchar* compiled_dir)
449 gchar *prefix = NULL, *dir = NULL;
452 prefix = gnc_gbr_find_prefix (NULL);
456 return g_strdup (default_dir ? default_dir : compiled_dir);
458 if (!g_getenv(
"GNC_UNINSTALLED"))
460 if (!g_strcmp0 (prefix, PREFIX))
464 return g_strdup (compiled_dir);
467 if (g_strcmp0 (compiled_dir, subdir) == 0)
474 return g_strdup (compiled_dir);
477 dir = g_build_filename (prefix, subdir, NULL);
498 gnc_gbr_find_bin_dir (
const gchar *default_bin_dir)
500 return find_component_directory (default_bin_dir, BINDIR);
518 gnc_gbr_find_data_dir (
const gchar *default_data_dir)
520 return find_component_directory (default_data_dir, DATADIR);
537 gnc_gbr_find_lib_dir (
const gchar *default_lib_dir)
539 return find_component_directory (default_lib_dir, LIBDIR);
556 gnc_gbr_find_etc_dir (
const gchar *default_etc_dir)
558 return find_component_directory (default_etc_dir, SYSCONFDIR);
gchar * gnc_file_path_relative_part(const gchar *prefix, const gchar *path)
Given a prefix and a path return the relative portion of the path.
File path resolution utility functions.