00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _PREFIX_C_
00027 #define _PREFIX_C_
00028
00029 #ifdef HAVE_CONFIG_H
00030 # include "config.h"
00031 #endif
00032
00033
00034
00035
00036 #ifndef BR_THREADS
00037
00038 #define BR_THREADS 1
00039 #include <glib.h>
00040 #endif
00041
00042 #include <cstdlib>
00043 #include <cstdio>
00044 #include <cstring>
00045 #include <limits.h>
00046 #include "prefix.h"
00047
00048
00049 #ifdef __cplusplus
00050 extern "C" {
00051 #endif
00052
00053
00054 #undef NULL
00055 #define NULL ((void *) 0)
00056
00057 #ifdef __GNUC__
00058 #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;}
00059 #else
00060 #define br_return_val_if_fail(expr,val) if (!(expr)) return val
00061 #endif
00062
00063
00064 #ifdef ENABLE_BINRELOC
00065
00066 #include <sys/types.h>
00067 #include <sys/stat.h>
00068 #include <sys/param.h>
00069 #include <unistd.h>
00070
00102 char *
00103 br_locate (void *symbol)
00104 {
00105 char line[5000];
00106 FILE *f;
00107 char *path;
00108
00109 br_return_val_if_fail (symbol != NULL, NULL);
00110
00111 f = fopen ("/proc/self/maps", "r");
00112 if (!f)
00113 return NULL;
00114
00115 while (!feof (f))
00116 {
00117 unsigned long start, end;
00118
00119 if (!fgets (line, sizeof (line), f))
00120 continue;
00121 if (!strstr (line, " r-xp ") || !strchr (line, '/'))
00122 continue;
00123
00124 sscanf (line, "%lx-%lx ", &start, &end);
00125 if (symbol >= (void *) start && symbol < (void *) end)
00126 {
00127 char *tmp;
00128 size_t len;
00129
00130
00131 path = strchr (line, '/');
00132
00133
00134 tmp = strrchr (path, '\n');
00135 if (tmp) *tmp = 0;
00136
00137
00138 len = strlen (path);
00139 if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
00140 {
00141 tmp = path + len - 10;
00142 *tmp = 0;
00143 }
00144
00145 fclose(f);
00146 return strdup (path);
00147 }
00148 }
00149
00150 fclose (f);
00151 return NULL;
00152 }
00153
00154
00168 char *
00169 br_locate_prefix (void *symbol)
00170 {
00171 char *path, *prefix;
00172
00173 br_return_val_if_fail (symbol != NULL, NULL);
00174
00175 path = br_locate (symbol);
00176 if (!path) return NULL;
00177
00178 prefix = br_extract_prefix (path);
00179 free (path);
00180 return prefix;
00181 }
00182
00183
00198 char *
00199 br_prepend_prefix (void *symbol, char *path)
00200 {
00201 char *tmp, *newpath;
00202
00203 br_return_val_if_fail (symbol != NULL, NULL);
00204 br_return_val_if_fail (path != NULL, NULL);
00205
00206 tmp = br_locate_prefix (symbol);
00207 if (!tmp) return NULL;
00208
00209 if (strcmp (tmp, "/") == 0)
00210 newpath = strdup (path);
00211 else
00212 newpath = br_strcat (tmp, path);
00213
00214
00215 if (0) br_prepend_prefix (NULL, NULL);
00216
00217 free (tmp);
00218 return newpath;
00219 }
00220
00221 #endif
00222
00223
00224
00225 #if BR_THREADS
00226
00227 GPrivate* br_thread_key = (GPrivate *)NULL;
00228
00229
00230
00231
00232
00233
00234
00235 #else
00236
00237 static char *br_last_value = (char*)NULL;
00238
00239 static void
00240 br_free_last_value ()
00241 {
00242 if (br_last_value)
00243 free (br_last_value);
00244 }
00245
00246 #endif
00247
00248
00264 const char *
00265 br_thread_local_store (char *str)
00266 {
00267 #if BR_THREADS
00268 if (!g_thread_supported ())
00269 {
00270 g_thread_init ((GThreadFunctions *)NULL);
00271 br_thread_key = g_private_new (g_free);
00272 }
00273
00274 char *specific = (char *) g_private_get (br_thread_key);
00275 if (specific)
00276 free (specific);
00277 g_private_set (br_thread_key, str);
00278
00279 #else
00280 static int initialized = 0;
00281
00282 if (!initialized)
00283 {
00284 atexit (br_free_last_value);
00285 initialized = 1;
00286 }
00287
00288 if (br_last_value)
00289 free (br_last_value);
00290 br_last_value = str;
00291 #endif
00292
00293 return (const char *) str;
00294 }
00295
00296
00305 char *
00306 br_strcat (const char *str1, const char *str2)
00307 {
00308 char *result;
00309 size_t len1, len2;
00310
00311 if (!str1) str1 = "";
00312 if (!str2) str2 = "";
00313
00314 len1 = strlen (str1);
00315 len2 = strlen (str2);
00316
00317 result = (char *) malloc (len1 + len2 + 1);
00318 memcpy (result, str1, len1);
00319 memcpy (result + len1, str2, len2);
00320 result[len1 + len2] = '\0';
00321
00322 return result;
00323 }
00324
00325
00326
00327 static char *
00328 br_strndup (char *str, size_t size)
00329 {
00330 char *result = (char*)NULL;
00331 size_t len;
00332
00333 br_return_val_if_fail (str != (char*)NULL, (char*)NULL);
00334
00335 len = strlen (str);
00336 if (!len) return strdup ("");
00337 if (size > len) size = len;
00338
00339 result = (char *) calloc (sizeof (char), len + 1);
00340 memcpy (result, str, size);
00341 return result;
00342 }
00343
00344
00356 char *
00357 br_extract_dir (const char *path)
00358 {
00359 char *end, *result;
00360
00361 br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
00362
00363 end = strrchr (path, '/');
00364 if (!end) return strdup (".");
00365
00366 while (end > path && *end == '/')
00367 end--;
00368 result = br_strndup ((char *) path, end - path + 1);
00369 if (!*result)
00370 {
00371 free (result);
00372 return strdup ("/");
00373 } else
00374 return result;
00375 }
00376
00377
00391 char *
00392 br_extract_prefix (const char *path)
00393 {
00394 char *end, *tmp, *result;
00395
00396 br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
00397
00398 if (!*path) return strdup ("/");
00399 end = strrchr (path, '/');
00400 if (!end) return strdup (path);
00401
00402 tmp = br_strndup ((char *) path, end - path);
00403 if (!*tmp)
00404 {
00405 free (tmp);
00406 return strdup ("/");
00407 }
00408 end = strrchr (tmp, '/');
00409 if (!end) return tmp;
00410
00411 result = br_strndup (tmp, end - tmp);
00412 free (tmp);
00413
00414 if (!*result)
00415 {
00416 free (result);
00417 result = strdup ("/");
00418 }
00419
00420 return result;
00421 }
00422
00423
00424 #ifdef __cplusplus
00425 }
00426 #endif
00427
00428
00429
00430 #ifdef __WIN32__
00431
00437 #include <windows.h>
00438 #include <glibmm/ustring.h>
00439
00443 static Glib::ustring win32_getExePath()
00444 {
00445 char exeName[MAX_PATH+1];
00446 GetModuleFileName(NULL, exeName, MAX_PATH);
00447 char *slashPos = strrchr(exeName, '\\');
00448 if (slashPos)
00449 *slashPos = '\0';
00450 Glib::ustring s = exeName;
00451 return s;
00452 }
00453
00454
00459 static Glib::ustring win32_getDataDir()
00460 {
00461 Glib::ustring dir = win32_getExePath();
00462 if (INKSCAPE_DATADIR && *INKSCAPE_DATADIR &&
00463 strcmp(INKSCAPE_DATADIR, ".") != 0)
00464 {
00465 dir += "\\";
00466 dir += INKSCAPE_DATADIR;
00467 }
00468 return dir;
00469 }
00470
00471 static Glib::ustring win32_getResourcePath(const Glib::ustring &childPath)
00472 {
00473 Glib::ustring dir = win32_getDataDir();
00474 if (childPath.size() > 0)
00475 {
00476 dir += "\\";
00477 dir += childPath;
00478 }
00479 return dir;
00480 }
00481
00482
00486 char *win32_relative_path(const char *childPath)
00487 {
00488 static char *returnPath = NULL;
00489 if (!childPath)
00490 childPath = "";
00491 Glib::ustring resourcePath = win32_getResourcePath(childPath);
00492 if (returnPath)
00493 free(returnPath);
00494 returnPath = strdup(resourcePath.c_str());
00495 return returnPath;
00496 }
00497 #endif
00498
00499
00500
00501
00502 #endif