/[gentoo-projects]/pax-utils/scanelf.c
Gentoo

Diff of /pax-utils/scanelf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.183 Revision 1.188
1/* 1/*
2 * Copyright 2003-2007 Gentoo Foundation 2 * Copyright 2003-2007 Gentoo Foundation
3 * Distributed under the terms of the GNU General Public License v2 3 * Distributed under the terms of the GNU General Public License v2
4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.183 2007/06/29 19:49:26 solar Exp $ 4 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.188 2007/08/31 17:45:24 solar Exp $
5 * 5 *
6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org> 6 * Copyright 2003-2007 Ned Ludd - <solar@gentoo.org>
7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org> 7 * Copyright 2004-2007 Mike Frysinger - <vapier@gentoo.org>
8 */ 8 */
9 9
10static const char *rcsid = "$Id: scanelf.c,v 1.188 2007/08/31 17:45:24 solar Exp $";
11const char * const argv0 = "scanelf";
12
10#include "paxinc.h" 13#include "paxinc.h"
11
12static const char *rcsid = "$Id: scanelf.c,v 1.183 2007/06/29 19:49:26 solar Exp $";
13#define argv0 "scanelf"
14 14
15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+') 15#define IS_MODIFIER(c) (c == '%' || c == '#' || c == '+')
16 16
17/* prototypes */ 17/* prototypes */
18static int file_matches_list(const char *filename, char **matchlist); 18static int file_matches_list(const char *filename, char **matchlist);
25static void scanelf_envpath(void); 25static void scanelf_envpath(void);
26static void usage(int status); 26static void usage(int status);
27static char **get_split_env(const char *envvar); 27static char **get_split_env(const char *envvar);
28static void parseenv(void); 28static void parseenv(void);
29static int parseargs(int argc, char *argv[]); 29static int parseargs(int argc, char *argv[]);
30static char *xstrdup(const char *s);
31static void *xmalloc(size_t size);
32static void *xrealloc(void *ptr, size_t size);
33static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n);
34#define xstrcat(dst,src,curr_len) xstrncat(dst,src,curr_len,0)
35static inline void xchrcat(char **dst, const char append, size_t *curr_len);
36static int rematch(const char *regex, const char *match, int cflags); 30static int rematch(const char *regex, const char *match, int cflags);
37 31
38/* variables to control behavior */ 32/* variables to control behavior */
39static char match_etypes[126] = ""; 33static char match_etypes[126] = "";
40static char *ldpaths[256]; 34static char *ldpaths[256];
80unsigned long setpax = 0UL; 74unsigned long setpax = 0UL;
81 75
82int has_objdump = 0; 76int has_objdump = 0;
83 77
84static char *getstr_perms(const char *fname); 78static char *getstr_perms(const char *fname);
85static char *getstr_perms(const char *fname) { 79static char *getstr_perms(const char *fname)
80{
86 struct stat st; 81 struct stat st;
87 static char buf[8]; 82 static char buf[8];
88 83
89 if ((stat(fname, &st)) == (-1)) 84 if ((stat(fname, &st)) == (-1))
90 return (char *) ""; 85 return (char *) "";
271 warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \ 266 warnf("%s: multiple PT_GNU_RELRO's !?", elf->filename); \
272 found = found_relro; \ 267 found = found_relro; \
273 offset = 4; \ 268 offset = 4; \
274 check_flags = PF_X; \ 269 check_flags = PF_X; \
275 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \ 270 } else if (EGET(phdr[i].p_type) == PT_LOAD) { \
276 if (ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC) \ 271 if (EGET(ehdr->e_type) == ET_DYN || EGET(ehdr->e_type) == ET_EXEC) \
277 if (multi_load++ > max_pt_load) \ 272 if (multi_load++ > max_pt_load) \
278 warnf("%s: more than %i PT_LOAD's !?", elf->filename, max_pt_load); \ 273 warnf("%s: more than %i PT_LOAD's !?", elf->filename, max_pt_load); \
279 if (file_matches_list(elf->filename, qa_wx_load)) \ 274 if (file_matches_list(elf->filename, qa_wx_load)) \
280 continue; \ 275 continue; \
281 found = found_load; \ 276 found = found_load; \
339 return NULL; 334 return NULL;
340 else 335 else
341 return ret; 336 return ret;
342} 337}
343 338
339/*
340 * See if this ELF contains a DT_TEXTREL tag in any of its
341 * PT_DYNAMIC sections.
342 */
344static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel) 343static const char *scanelf_file_textrel(elfobj *elf, char *found_textrel)
345{ 344{
346 static const char *ret = "TEXTREL"; 345 static const char *ret = "TEXTREL";
347 unsigned long i; 346 unsigned long i;
348 347
356 Elf ## B ## _Dyn *dyn; \ 355 Elf ## B ## _Dyn *dyn; \
357 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 356 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
358 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 357 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
359 Elf ## B ## _Off offset; \ 358 Elf ## B ## _Off offset; \
360 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 359 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
361 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 360 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) continue; \
362 offset = EGET(phdr[i].p_offset); \ 361 offset = EGET(phdr[i].p_offset); \
363 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 362 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
364 dyn = DYN ## B (elf->data + offset); \ 363 dyn = DYN ## B (elf->data + offset); \
365 while (EGET(dyn->d_tag) != DT_NULL) { \ 364 while (EGET(dyn->d_tag) != DT_NULL) { \
366 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ 365 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \
379 return NULL; 378 return NULL;
380 else 379 else
381 return " - "; 380 return " - ";
382} 381}
383 382
383/*
384 * Scan the .text section to see if there are any relocations in it.
385 * Should rewrite this to check PT_LOAD sections that are marked
386 * Executable rather than the section named '.text'.
387 */
384static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel) 388static char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char *found_textrel)
385{ 389{
386 unsigned long s, r, rmax; 390 unsigned long s, r, rmax;
387 void *symtab_void, *strtab_void, *text_void; 391 void *symtab_void, *strtab_void, *text_void;
388 392
479 printf("%s", func_name); \ 483 printf("%s", func_name); \
480 } else \ 484 } else \
481 printf("(optimized out)"); \ 485 printf("(optimized out)"); \
482 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \ 486 printf(" [0x%lX]\n", (unsigned long)offset_tmp); \
483 if (be_verbose && has_objdump) { \ 487 if (be_verbose && has_objdump) { \
488 Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \
484 char *sysbuf; \ 489 char *sysbuf; \
485 size_t syslen; \ 490 size_t syslen; \
486 const char sysfmt[] = "objdump -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \ 491 const char sysfmt[] = "objdump -r -R -d -w -l --start-address=0x%lX --stop-address=0x%lX %s | grep --color -i -C 3 '.*[[:space:]]%lX:[[:space:]]*R_.*'\n"; \
487 syslen = sizeof(sysfmt) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \ 492 syslen = sizeof(sysfmt) + strlen(elf->filename) + 3 * sizeof(unsigned long) + 1; \
488 sysbuf = xmalloc(syslen); \ 493 sysbuf = xmalloc(syslen); \
489 if (sysbuf) { \
490 Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \
491 if (end_addr < r_offset) \ 494 if (end_addr < r_offset) \
492 /* not uncommon when things are optimized out */ \ 495 /* not uncommon when things are optimized out */ \
493 end_addr = r_offset + 0x100; \ 496 end_addr = r_offset + 0x100; \
494 snprintf(sysbuf, syslen, sysfmt, \ 497 snprintf(sysbuf, syslen, sysfmt, \
495 (unsigned long)offset_tmp, \ 498 (unsigned long)offset_tmp, \
496 (unsigned long)end_addr, \ 499 (unsigned long)end_addr, \
497 elf->filename, \ 500 elf->filename, \
498 (unsigned long)r_offset); \ 501 (unsigned long)r_offset); \
499 fflush(stdout); \ 502 fflush(stdout); \
500 system(sysbuf); \ 503 system(sysbuf); \
501 fflush(stdout); \ 504 fflush(stdout); \
502 free(sysbuf); \ 505 free(sysbuf); \
503 } \
504 } \ 506 } \
505 } \ 507 } \
506 } } 508 } }
507 SHOW_TEXTRELS(32) 509 SHOW_TEXTRELS(32)
508 SHOW_TEXTRELS(64) 510 SHOW_TEXTRELS(64)
558 Elf ## B ## _Off offset; \ 560 Elf ## B ## _Off offset; \
559 Elf ## B ## _Xword word; \ 561 Elf ## B ## _Xword word; \
560 /* Scan all the program headers */ \ 562 /* Scan all the program headers */ \
561 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 563 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
562 /* Just scan dynamic headers */ \ 564 /* Just scan dynamic headers */ \
563 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 565 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) continue; \
564 offset = EGET(phdr[i].p_offset); \ 566 offset = EGET(phdr[i].p_offset); \
565 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 567 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
566 /* Just scan dynamic RPATH/RUNPATH headers */ \ 568 /* Just scan dynamic RPATH/RUNPATH headers */ \
567 dyn = DYN ## B (elf->data + offset); \ 569 dyn = DYN ## B (elf->data + offset); \
568 while ((word=EGET(dyn->d_tag)) != DT_NULL) { \ 570 while ((word=EGET(dyn->d_tag)) != DT_NULL) { \
818 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 820 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
819 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 821 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
820 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 822 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
821 Elf ## B ## _Off offset; \ 823 Elf ## B ## _Off offset; \
822 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 824 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
823 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 825 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) continue; \
824 offset = EGET(phdr[i].p_offset); \ 826 offset = EGET(phdr[i].p_offset); \
825 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 827 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
826 dyn = DYN ## B (elf->data + offset); \ 828 dyn = DYN ## B (elf->data + offset); \
827 while (EGET(dyn->d_tag) != DT_NULL) { \ 829 while (EGET(dyn->d_tag) != DT_NULL) { \
828 if (EGET(dyn->d_tag) == DT_NEEDED) { \ 830 if (EGET(dyn->d_tag) == DT_NEEDED) { \
893 Elf ## B ## _Dyn *dyn; \ 895 Elf ## B ## _Dyn *dyn; \
894 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 896 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
895 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 897 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
896 Elf ## B ## _Off offset; \ 898 Elf ## B ## _Off offset; \
897 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 899 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
898 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 900 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) continue; \
899 dynamic = 1; \ 901 dynamic = 1; \
900 offset = EGET(phdr[i].p_offset); \ 902 offset = EGET(phdr[i].p_offset); \
901 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 903 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
902 dyn = DYN ## B (elf->data + offset); \ 904 dyn = DYN ## B (elf->data + offset); \
903 while (EGET(dyn->d_tag) != DT_NULL) { \ 905 while (EGET(dyn->d_tag) != DT_NULL) { \
942 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 944 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
943 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 945 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
944 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 946 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
945 Elf ## B ## _Off offset; \ 947 Elf ## B ## _Off offset; \
946 /* only look for soname in shared objects */ \ 948 /* only look for soname in shared objects */ \
947 if (ehdr->e_type != ET_DYN) \ 949 if (EGET(ehdr->e_type) != ET_DYN) \
948 return NULL; \ 950 return NULL; \
949 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 951 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
950 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 952 if (EGET(phdr[i].p_type) != PT_DYNAMIC || EGET(phdr[i].p_filesz) == 0) continue; \
951 offset = EGET(phdr[i].p_offset); \ 953 offset = EGET(phdr[i].p_offset); \
952 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \ 954 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
953 dyn = DYN ## B (elf->data + offset); \ 955 dyn = DYN ## B (elf->data + offset); \
954 while (EGET(dyn->d_tag) != DT_NULL) { \ 956 while (EGET(dyn->d_tag) != DT_NULL) { \
955 if (EGET(dyn->d_tag) == DT_SONAME) { \ 957 if (EGET(dyn->d_tag) == DT_SONAME) { \
1120 printf("%s: scanning file\n", elf->filename); 1122 printf("%s: scanning file\n", elf->filename);
1121 1123
1122 /* init output buffer */ 1124 /* init output buffer */
1123 if (!out_buffer) { 1125 if (!out_buffer) {
1124 out_len = sizeof(char) * 80; 1126 out_len = sizeof(char) * 80;
1125 out_buffer = (char*)xmalloc(out_len); 1127 out_buffer = xmalloc(out_len);
1126 } 1128 }
1127 *out_buffer = '\0'; 1129 *out_buffer = '\0';
1128 1130
1129 /* show the header */ 1131 /* show the header */
1130 if (!be_quiet && show_banner) { 1132 if (!be_quiet && show_banner) {
1278 if (strlen(match_etypes)) { 1280 if (strlen(match_etypes)) {
1279 char sbuf[126]; 1281 char sbuf[126];
1280 strncpy(sbuf, match_etypes, sizeof(sbuf)); 1282 strncpy(sbuf, match_etypes, sizeof(sbuf));
1281 if (strchr(match_etypes, ',') != NULL) { 1283 if (strchr(match_etypes, ',') != NULL) {
1282 char *p; 1284 char *p;
1283 while((p = strrchr(sbuf, ',')) != NULL) { 1285 while ((p = strrchr(sbuf, ',')) != NULL) {
1284 *p = 0; 1286 *p = 0;
1285 if (etype_lookup(p+1) == get_etype(elf)) 1287 if (etype_lookup(p+1) == get_etype(elf))
1286 goto label_ret; 1288 goto label_ret;
1287 } 1289 }
1288 } 1290 }
1449 if ((p = strrchr(path, '\r')) != NULL) 1451 if ((p = strrchr(path, '\r')) != NULL)
1450 *p = 0; 1452 *p = 0;
1451 if ((p = strchr(path, '\n')) != NULL) 1453 if ((p = strchr(path, '\n')) != NULL)
1452 *p = 0; 1454 *p = 0;
1453#ifdef __linux__ 1455#ifdef __linux__
1454 // recursive includes of the same file will make this segfault. 1456 /* recursive includes of the same file will make this segfault. */
1455 if ((memcmp(path, "include", 7) == 0) && isblank(path[7])) { 1457 if ((memcmp(path, "include", 7) == 0) && isblank(path[7])) {
1456 glob64_t gl; 1458 glob64_t gl;
1457 size_t x; 1459 size_t x;
1458 char gpath[__PAX_UTILS_PATH_MAX]; 1460 char gpath[__PAX_UTILS_PATH_MAX];
1459 1461
1514 { 1516 {
1515 fclose(fp); 1517 fclose(fp);
1516 return i; 1518 return i;
1517 } 1519 }
1518 1520
1519 b = (char*)malloc(hdr.dirlistlen+1); 1521 b = xmalloc(hdr.dirlistlen + 1);
1520 if (fread(b, 1, hdr.dirlistlen+1, fp) != hdr.dirlistlen+1) { 1522 if (fread(b, 1, hdr.dirlistlen+1, fp) != hdr.dirlistlen+1) {
1521 fclose(fp); 1523 fclose(fp);
1522 free(b); 1524 free(b);
1523 return i; 1525 return i;
1524 } 1526 }
1546} 1548}
1547 1549
1548#endif 1550#endif
1549 1551
1550/* scan /etc/ld.so.conf for paths */ 1552/* scan /etc/ld.so.conf for paths */
1551static void scanelf_ldpath() 1553static void scanelf_ldpath(void)
1552{ 1554{
1553 char scan_l, scan_ul, scan_ull; 1555 char scan_l, scan_ul, scan_ull;
1554 int i = 0; 1556 int i = 0;
1555 1557
1556 if (!ldpaths[0]) 1558 if (!ldpaths[0])
1570 if (!scan_ul) scanelf_dir("/usr/lib"); 1572 if (!scan_ul) scanelf_dir("/usr/lib");
1571 if (!scan_ull) scanelf_dir("/usr/local/lib"); 1573 if (!scan_ull) scanelf_dir("/usr/local/lib");
1572} 1574}
1573 1575
1574/* scan env PATH for paths */ 1576/* scan env PATH for paths */
1575static void scanelf_envpath() 1577static void scanelf_envpath(void)
1576{ 1578{
1577 char *path, *p; 1579 char *path, *p;
1578 1580
1579 path = getenv("PATH"); 1581 path = getenv("PATH");
1580 if (!path) 1582 if (!path)
1746 find_section = optarg; 1748 find_section = optarg;
1747 break; 1749 break;
1748 case 's': { 1750 case 's': {
1749 if (find_sym) warn("You prob don't want to specify -s twice"); 1751 if (find_sym) warn("You prob don't want to specify -s twice");
1750 find_sym = optarg; 1752 find_sym = optarg;
1751 versioned_symname = (char*)xmalloc(sizeof(char) * (strlen(find_sym)+1+1)); 1753 versioned_symname = xmalloc(sizeof(char) * (strlen(find_sym)+1+1));
1752 sprintf(versioned_symname, "%s@", find_sym); 1754 sprintf(versioned_symname, "%s@", find_sym);
1753 break; 1755 break;
1754 } 1756 }
1755 case 'N': { 1757 case 'N': {
1756 if (find_lib) warn("You prob don't want to specify -N twice"); 1758 if (find_lib) warn("You prob don't want to specify -N twice");
1765 } 1767 }
1766 case 'z': { 1768 case 'z': {
1767 unsigned long flags = (PF_NOEMUTRAMP | PF_NORANDEXEC); 1769 unsigned long flags = (PF_NOEMUTRAMP | PF_NORANDEXEC);
1768 size_t x; 1770 size_t x;
1769 1771
1770 for (x = 0 ; x < strlen(optarg); x++) { 1772 for (x = 0; x < strlen(optarg); x++) {
1771 switch(optarg[x]) { 1773 switch (optarg[x]) {
1772 case 'p': 1774 case 'p':
1773 case 'P': 1775 case 'P':
1774 do_pax_state(optarg[x], PAGEEXEC); 1776 do_pax_state(optarg[x], PAGEEXEC);
1775 break; 1777 break;
1776 case 's': 1778 case 's':
1880 } 1882 }
1881 1883
1882 /* construct our default format */ 1884 /* construct our default format */
1883 } else { 1885 } else {
1884 size_t fmt_len = 30; 1886 size_t fmt_len = 30;
1885 out_format = (char*)xmalloc(sizeof(char) * fmt_len); 1887 out_format = xmalloc(sizeof(char) * fmt_len);
1886 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len); 1888 if (!be_quiet) xstrcat(&out_format, "%o ", &fmt_len);
1887 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len); 1889 if (show_pax) xstrcat(&out_format, "%x ", &fmt_len);
1888 if (show_perms) xstrcat(&out_format, "%O ", &fmt_len); 1890 if (show_perms) xstrcat(&out_format, "%O ", &fmt_len);
1889 if (show_endian) xstrcat(&out_format, "%D ", &fmt_len); 1891 if (show_endian) xstrcat(&out_format, "%D ", &fmt_len);
1890 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len); 1892 if (show_phdr) xstrcat(&out_format, "%e ", &fmt_len);
1962 /* don't want to free(env) as it contains the memory that backs 1964 /* don't want to free(env) as it contains the memory that backs
1963 * the envvals array of strings */ 1965 * the envvals array of strings */
1964 return envvals; 1966 return envvals;
1965} 1967}
1966 1968
1967static void parseenv() 1969static void parseenv(void)
1968{ 1970{
1969 qa_textrels = get_split_env("QA_TEXTRELS"); 1971 qa_textrels = get_split_env("QA_TEXTRELS");
1970 qa_execstack = get_split_env("QA_EXECSTACK"); 1972 qa_execstack = get_split_env("QA_EXECSTACK");
1971 qa_wx_load = get_split_env("QA_WX_LOAD"); 1973 qa_wx_load = get_split_env("QA_WX_LOAD");
1972} 1974}
1973 1975
1974#ifdef __PAX_UTILS_CLEANUP 1976#ifdef __PAX_UTILS_CLEANUP
1975static void cleanup() 1977static void cleanup(void)
1976{ 1978{
1977 free(out_format); 1979 free(out_format);
1978 free(qa_textrels); 1980 free(qa_textrels);
1979 free(qa_execstack); 1981 free(qa_execstack);
1980 free(qa_wx_load); 1982 free(qa_wx_load);
1998#endif 2000#endif
1999 return ret; 2001 return ret;
2000} 2002}
2001 2003
2002 2004
2003
2004/* utility funcs */
2005static char *xstrdup(const char *s)
2006{
2007 char *ret = strdup(s);
2008 if (!ret) err("Could not strdup(): %s", strerror(errno));
2009 return ret;
2010}
2011static void *xmalloc(size_t size)
2012{
2013 void *ret = malloc(size);
2014 if (!ret) err("Could not malloc() %li bytes", (unsigned long)size);
2015 return ret;
2016}
2017static void *xrealloc(void *ptr, size_t size)
2018{
2019 void *ret = realloc(ptr, size);
2020 if (!ret) err("Could not realloc() %li bytes", (unsigned long)size);
2021 return ret;
2022}
2023static void xstrncat(char **dst, const char *src, size_t *curr_len, size_t n)
2024{
2025 size_t new_len;
2026
2027 new_len = strlen(*dst) + strlen(src);
2028 if (*curr_len <= new_len) {
2029 *curr_len = new_len + (*curr_len / 2);
2030 *dst = realloc(*dst, *curr_len);
2031 if (!*dst)
2032 err("could not realloc() %li bytes", (unsigned long)*curr_len);
2033 }
2034
2035 if (n)
2036 strncat(*dst, src, n);
2037 else
2038 strcat(*dst, src);
2039}
2040static inline void xchrcat(char **dst, const char append, size_t *curr_len)
2041{
2042 static char my_app[2];
2043 my_app[0] = append;
2044 my_app[1] = '\0';
2045 xstrcat(dst, my_app, curr_len);
2046}
2047
2048/* Match filename against entries in matchlist, return TRUE 2005/* Match filename against entries in matchlist, return TRUE
2049 * if the file is listed */ 2006 * if the file is listed */
2050static int file_matches_list(const char *filename, char **matchlist) 2007static int file_matches_list(const char *filename, char **matchlist)
2051{ 2008{
2052 char **file; 2009 char **file;

Legend:
Removed from v.1.183  
changed lines
  Added in v.1.188

  ViewVC Help
Powered by ViewVC 1.1.20