#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "binreloc.h"
Go to the source code of this file.
Defines | |
#define | NULL ((void *) 0) |
Functions | |
static char * | _br_find_exe (BrInitError *error) |
static char * | _br_find_exe_for_symbol (const void *symbol, BrInitError *error) |
int | SlLp57100427862049_br_init (BrInitError *error) |
int | SlLp57100427862049_br_init_lib (BrInitError *error) |
char * | SlLp57100427862049_br_find_exe (const char *default_exe) |
char * | SlLp57100427862049_br_find_exe_dir (const char *default_dir) |
char * | SlLp57100427862049_br_find_prefix (const char *default_prefix) |
char * | SlLp57100427862049_br_find_bin_dir (const char *default_bin_dir) |
char * | SlLp57100427862049_br_find_sbin_dir (const char *default_sbin_dir) |
char * | SlLp57100427862049_br_find_data_dir (const char *default_data_dir) |
char * | SlLp57100427862049_br_find_locale_dir (const char *default_locale_dir) |
char * | SlLp57100427862049_br_find_lib_dir (const char *default_lib_dir) |
char * | SlLp57100427862049_br_find_libexec_dir (const char *default_libexec_dir) |
char * | SlLp57100427862049_br_find_etc_dir (const char *default_etc_dir) |
char * | SlLp57100427862049_br_strcat (const char *str1, const char *str2) |
char * | SlLp57100427862049_br_build_path (const char *dir, const char *file) |
static char * | br_strndup (const char *str, size_t size) |
char * | SlLp57100427862049_br_dirname (const char *path) |
Variables | |
static char * | exe = (char *) ((void *) 0) |
|
Definition at line 383 of file binreloc.c. |
|
Definition at line 139 of file binreloc.c. 00140 { 00141 #ifndef ENABLE_BINRELOC 00142 if (error) 00143 *error = BR_INIT_ERROR_DISABLED; 00144 return NULL; 00145 #else 00146 char *path, *path2, *line, *result; 00147 size_t buf_size; 00148 ssize_t size; 00149 struct stat stat_buf; 00150 FILE *f; 00151 00152 /* Read from /proc/self/exe (symlink) */ 00153 if (sizeof (path) > SSIZE_MAX) 00154 buf_size = SSIZE_MAX - 1; 00155 else 00156 buf_size = PATH_MAX - 1; 00157 path = (char *) malloc (buf_size); 00158 if (path == NULL) { 00159 /* Cannot allocate memory. */ 00160 if (error) 00161 *error = BR_INIT_ERROR_NOMEM; 00162 return NULL; 00163 } 00164 path2 = (char *) malloc (buf_size); 00165 if (path2 == NULL) { 00166 /* Cannot allocate memory. */ 00167 if (error) 00168 *error = BR_INIT_ERROR_NOMEM; 00169 free (path); 00170 return NULL; 00171 } 00172 00173 strncpy (path2, "/proc/self/exe", buf_size - 1); 00174 00175 while (1) { 00176 int i; 00177 00178 size = readlink (path2, path, buf_size - 1); 00179 if (size == -1) { 00180 /* Error. */ 00181 free (path2); 00182 break; 00183 } 00184 00185 /* readlink() success. */ 00186 path[size] = '\0'; 00187 00188 /* Check whether the symlink's target is also a symlink. 00189 * We want to get the final target. */ 00190 i = stat (path, &stat_buf); 00191 if (i == -1) { 00192 /* Error. */ 00193 free (path2); 00194 break; 00195 } 00196 00197 /* stat() success. */ 00198 if (!S_ISLNK (stat_buf.st_mode)) { 00199 /* path is not a symlink. Done. */ 00200 free (path2); 00201 return path; 00202 } 00203 00204 /* path is a symlink. Continue loop and resolve this. */ 00205 strncpy (path, path2, buf_size - 1); 00206 } 00207 00208 00209 /* readlink() or stat() failed; this can happen when the program is 00210 * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */ 00211 00212 buf_size = PATH_MAX + 128; 00213 line = (char *) realloc (path, buf_size); 00214 if (line == NULL) { 00215 /* Cannot allocate memory. */ 00216 free (path); 00217 if (error) 00218 *error = BR_INIT_ERROR_NOMEM; 00219 return NULL; 00220 } 00221 00222 f = fopen ("/proc/self/maps", "r"); 00223 if (f == NULL) { 00224 free (line); 00225 if (error) 00226 *error = BR_INIT_ERROR_OPEN_MAPS; 00227 return NULL; 00228 } 00229 00230 /* The first entry should be the executable name. */ 00231 result = fgets (line, (int) buf_size, f); 00232 if (result == NULL) { 00233 fclose (f); 00234 free (line); 00235 if (error) 00236 *error = BR_INIT_ERROR_READ_MAPS; 00237 return NULL; 00238 } 00239 00240 /* Get rid of newline character. */ 00241 buf_size = strlen (line); 00242 if (buf_size <= 0) { 00243 /* Huh? An empty string? */ 00244 fclose (f); 00245 free (line); 00246 if (error) 00247 *error = BR_INIT_ERROR_INVALID_MAPS; 00248 return NULL; 00249 } 00250 if (line[buf_size - 1] == 10) 00251 line[buf_size - 1] = 0; 00252 00253 /* Extract the filename; it is always an absolute path. */ 00254 path = strchr (line, '/'); 00255 00256 /* Sanity check. */ 00257 if (strstr (line, " r-xp ") == NULL || path == NULL) { 00258 fclose (f); 00259 free (line); 00260 if (error) 00261 *error = BR_INIT_ERROR_INVALID_MAPS; 00262 return NULL; 00263 } 00264 00265 path = strdup (path); 00266 free (line); 00267 fclose (f); 00268 return path; 00269 #endif /* ENABLE_BINRELOC */ 00270 }
|
|
Definition at line 278 of file binreloc.c. 00279 { 00280 #ifndef ENABLE_BINRELOC 00281 if (error) 00282 *error = BR_INIT_ERROR_DISABLED; 00283 return (char *) NULL; 00284 #else 00285 #define SIZE PATH_MAX + 100 00286 FILE *f; 00287 size_t address_string_len; 00288 char *address_string, line[SIZE], *found; 00289 00290 if (symbol == NULL) 00291 return (char *) NULL; 00292 00293 f = fopen ("/proc/self/maps", "r"); 00294 if (f == NULL) 00295 return (char *) NULL; 00296 00297 address_string_len = 4; 00298 address_string = (char *) malloc (address_string_len); 00299 found = (char *) NULL; 00300 00301 while (!feof (f)) { 00302 char *start_addr, *end_addr, *end_addr_end, *file; 00303 void *start_addr_p, *end_addr_p; 00304 size_t len; 00305 00306 if (fgets (line, SIZE, f) == NULL) 00307 break; 00308 00309 /* Sanity check. */ 00310 if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL) 00311 continue; 00312 00313 /* Parse line. */ 00314 start_addr = line; 00315 end_addr = strchr (line, '-'); 00316 file = strchr (line, '/'); 00317 00318 /* More sanity check. */ 00319 if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-')) 00320 continue; 00321 00322 end_addr[0] = '\0'; 00323 end_addr++; 00324 end_addr_end = strchr (end_addr, ' '); 00325 if (end_addr_end == NULL) 00326 continue; 00327 00328 end_addr_end[0] = '\0'; 00329 len = strlen (file); 00330 if (len == 0) 00331 continue; 00332 if (file[len - 1] == '\n') 00333 file[len - 1] = '\0'; 00334 00335 /* Get rid of "(deleted)" from the filename. */ 00336 len = strlen (file); 00337 if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0) 00338 file[len - 10] = '\0'; 00339 00340 /* I don't know whether this can happen but better safe than sorry. */ 00341 len = strlen (start_addr); 00342 if (len != strlen (end_addr)) 00343 continue; 00344 00345 00346 /* Transform the addresses into a string in the form of 0xdeadbeef, 00347 * then transform that into a pointer. */ 00348 if (address_string_len < len + 3) { 00349 address_string_len = len + 3; 00350 address_string = (char *) realloc (address_string, address_string_len); 00351 } 00352 00353 memcpy (address_string, "0x", 2); 00354 memcpy (address_string + 2, start_addr, len); 00355 address_string[2 + len] = '\0'; 00356 sscanf (address_string, "%p", &start_addr_p); 00357 00358 memcpy (address_string, "0x", 2); 00359 memcpy (address_string + 2, end_addr, len); 00360 address_string[2 + len] = '\0'; 00361 sscanf (address_string, "%p", &end_addr_p); 00362 00363 00364 if (symbol >= start_addr_p && symbol < end_addr_p) { 00365 found = file; 00366 break; 00367 } 00368 } 00369 00370 free (address_string); 00371 fclose (f); 00372 00373 if (found == NULL) 00374 return (char *) NULL; 00375 else 00376 return strdup (found); 00377 #endif /* ENABLE_BINRELOC */ 00378 }
|
|
Definition at line 806 of file binreloc.c. 00807 { 00808 char *result = (char *) NULL; 00809 size_t len; 00810 00811 if (str == (const char *) NULL) 00812 return (char *) NULL; 00813 00814 len = strlen (str); 00815 if (len == 0) 00816 return strdup (""); 00817 if (size > len) 00818 size = len; 00819 00820 result = (char *) malloc (len + 1); 00821 memcpy (result, str, size); 00822 result[size] = '\0'; 00823 return result; 00824 }
|
|
Definition at line 784 of file binreloc.c. 00785 { 00786 char *dir2, *result; 00787 size_t len; 00788 int must_free = 0; 00789 00790 len = strlen (dir); 00791 if (len > 0 && dir[len - 1] != '/') { 00792 dir2 = br_strcat (dir, "/"); 00793 must_free = 1; 00794 } else 00795 dir2 = (char *) dir; 00796 00797 result = br_strcat (dir2, file); 00798 if (must_free) 00799 free (dir2); 00800 return result; 00801 }
|
|
Extracts the directory component of a path. Similar to g_dirname() or the dirname commandline application. Example: br_dirname ("/usr/local/foobar"); --> Returns: "/usr/local"
Definition at line 840 of file binreloc.c. 00841 { 00842 char *end, *result; 00843 00844 if (path == (const char *) NULL) 00845 return (char *) NULL; 00846 00847 end = strrchr (path, '/'); 00848 if (end == (const char *) NULL) 00849 return strdup ("."); 00850 00851 while (end > path && *end == '/') 00852 end--; 00853 result = br_strndup (path, end - path + 1); 00854 if (result[0] == 0) { 00855 free (result); 00856 return strdup ("/"); 00857 } else 00858 return result; 00859 }
|
|
Locate the application's binary folder. The path is generated by the following pseudo-code evaluation: prefix + "/bin"
Definition at line 532 of file binreloc.c. 00533 { 00534 char *prefix, *dir; 00535 00536 prefix = br_find_prefix ((const char *) NULL); 00537 if (prefix == (char *) NULL) { 00538 /* BinReloc not initialized. */ 00539 if (default_bin_dir != (const char *) NULL) 00540 return strdup (default_bin_dir); 00541 else 00542 return (char *) NULL; 00543 } 00544 00545 dir = br_build_path (prefix, "bin"); 00546 free (prefix); 00547 return dir; 00548 }
|
|
Locate the application's data folder. The path is generated by the following pseudo-code evaluation: prefix + "/share"
Definition at line 599 of file binreloc.c. 00600 { 00601 char *prefix, *dir; 00602 00603 prefix = br_find_prefix ((const char *) NULL); 00604 if (prefix == (char *) NULL) { 00605 /* BinReloc not initialized. */ 00606 if (default_data_dir != (const char *) NULL) 00607 return strdup (default_data_dir); 00608 else 00609 return (char *) NULL; 00610 } 00611 00612 dir = br_build_path (prefix, "share"); 00613 free (prefix); 00614 return dir; 00615 }
|
|
Locate the application's configuration files folder. The path is generated by the following pseudo-code evaluation: prefix + "/etc"
Definition at line 731 of file binreloc.c. 00732 { 00733 char *prefix, *dir; 00734 00735 prefix = br_find_prefix ((const char *) NULL); 00736 if (prefix == (char *) NULL) { 00737 /* BinReloc not initialized. */ 00738 if (default_etc_dir != (const char *) NULL) 00739 return strdup (default_etc_dir); 00740 else 00741 return (char *) NULL; 00742 } 00743 00744 dir = br_build_path (prefix, "etc"); 00745 free (prefix); 00746 return dir; 00747 }
|
|
Find the canonical filename of the current application.
Definition at line 443 of file binreloc.c. 00444 { 00445 if (exe == (char *) NULL) { 00446 /* BinReloc is not initialized. */ 00447 if (default_exe != (const char *) NULL) 00448 return strdup (default_exe); 00449 else 00450 return (char *) NULL; 00451 } 00452 return strdup (exe); 00453 }
|
|
Locate the directory in which the current application is installed. The prefix is generated by the following pseudo-code evaluation: dirname(exename)
Definition at line 471 of file binreloc.c. 00472 { 00473 if (exe == NULL) { 00474 /* BinReloc not initialized. */ 00475 if (default_dir != NULL) 00476 return strdup (default_dir); 00477 else 00478 return NULL; 00479 } 00480 00481 return br_dirname (exe); 00482 }
|
|
Locate the application's library folder. The path is generated by the following pseudo-code evaluation: prefix + "/lib"
Definition at line 665 of file binreloc.c. 00666 { 00667 char *prefix, *dir; 00668 00669 prefix = br_find_prefix ((const char *) NULL); 00670 if (prefix == (char *) NULL) { 00671 /* BinReloc not initialized. */ 00672 if (default_lib_dir != (const char *) NULL) 00673 return strdup (default_lib_dir); 00674 else 00675 return (char *) NULL; 00676 } 00677 00678 dir = br_build_path (prefix, "lib"); 00679 free (prefix); 00680 return dir; 00681 }
|
|
Locate the application's libexec folder. The path is generated by the following pseudo-code evaluation: prefix + "/libexec"
Definition at line 698 of file binreloc.c. 00699 { 00700 char *prefix, *dir; 00701 00702 prefix = br_find_prefix ((const char *) NULL); 00703 if (prefix == (char *) NULL) { 00704 /* BinReloc not initialized. */ 00705 if (default_libexec_dir != (const char *) NULL) 00706 return strdup (default_libexec_dir); 00707 else 00708 return (char *) NULL; 00709 } 00710 00711 dir = br_build_path (prefix, "libexec"); 00712 free (prefix); 00713 return dir; 00714 }
|
|
Locate the application's localization folder. The path is generated by the following pseudo-code evaluation: prefix + "/share/locale"
Definition at line 632 of file binreloc.c. 00633 { 00634 char *data_dir, *dir; 00635 00636 data_dir = br_find_data_dir ((const char *) NULL); 00637 if (data_dir == (char *) NULL) { 00638 /* BinReloc not initialized. */ 00639 if (default_locale_dir != (const char *) NULL) 00640 return strdup (default_locale_dir); 00641 else 00642 return (char *) NULL; 00643 } 00644 00645 dir = br_build_path (data_dir, "locale"); 00646 free (data_dir); 00647 return dir; 00648 }
|
|
Locate the prefix in which the current application is installed. The prefix is generated by the following pseudo-code evaluation: dirname(dirname(exename))
Definition at line 499 of file binreloc.c. 00500 { 00501 char *dir1, *dir2; 00502 00503 if (exe == (char *) NULL) { 00504 /* BinReloc not initialized. */ 00505 if (default_prefix != (const char *) NULL) 00506 return strdup (default_prefix); 00507 else 00508 return (char *) NULL; 00509 } 00510 00511 dir1 = br_dirname (exe); 00512 dir2 = br_dirname (dir1); 00513 free (dir1); 00514 return dir2; 00515 }
|
|
Locate the application's superuser binary folder. The path is generated by the following pseudo-code evaluation: prefix + "/sbin"
Definition at line 565 of file binreloc.c. 00566 { 00567 char *prefix, *dir; 00568 00569 prefix = br_find_prefix ((const char *) NULL); 00570 if (prefix == (char *) NULL) { 00571 /* BinReloc not initialized. */ 00572 if (default_sbin_dir != (const char *) NULL) 00573 return strdup (default_sbin_dir); 00574 else 00575 return (char *) NULL; 00576 } 00577 00578 dir = br_build_path (prefix, "sbin"); 00579 free (prefix); 00580 return dir; 00581 }
|
|
Initialize the BinReloc library (for applications). This function must be called before using any other BinReloc functions. It attempts to locate the application's canonical filename.
Definition at line 404 of file binreloc.c. 00405 { 00406 exe = _br_find_exe (error); 00407 return exe != NULL; 00408 }
|
|
Initialize the BinReloc library (for libraries). This function must be called before using any other BinReloc functions. It attempts to locate the calling library's canonical filename.
Definition at line 426 of file binreloc.c. 00427 { 00428 exe = _br_find_exe_for_symbol ((const void *) "", error); 00429 return exe != NULL; 00430 }
|
|
Concatenate str1 and str2 to a newly allocated string.
Definition at line 761 of file binreloc.c. 00762 { 00763 char *result; 00764 size_t len1, len2; 00765 00766 if (str1 == NULL) 00767 str1 = ""; 00768 if (str2 == NULL) 00769 str2 = ""; 00770 00771 len1 = strlen (str1); 00772 len2 = strlen (str2); 00773 00774 result = (char *) malloc (len1 + len2 + 1); 00775 memcpy (result, str1, len1); 00776 memcpy (result + len1, str2, len2); 00777 result[len1 + len2] = '\0'; 00778 00779 return result; 00780 }
|
|
Definition at line 386 of file binreloc.c. |