/[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.43 Revision 1.47
1/* 1/*
2 * Copyright 2003 Ned Ludd <solar@gentoo.org> 2 * Copyright 2003 Ned Ludd <solar@gentoo.org>
3 * Copyright 1999-2005 Gentoo Foundation 3 * Copyright 1999-2005 Gentoo Foundation
4 * Distributed under the terms of the GNU General Public License v2 4 * Distributed under the terms of the GNU General Public License v2
5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.43 2005/05/06 02:55:27 vapier Exp $ 5 * $Header: /var/cvsroot/gentoo-projects/pax-utils/Attic/scanelf.c,v 1.47 2005/05/18 01:08:46 vapier Exp $
6 * 6 *
7 ******************************************************************** 7 ********************************************************************
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as 9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the 10 * published by the Free Software Foundation; either version 2 of the
33#include <getopt.h> 33#include <getopt.h>
34#include <assert.h> 34#include <assert.h>
35 35
36#include "paxelf.h" 36#include "paxelf.h"
37 37
38static const char *rcsid = "$Id: scanelf.c,v 1.43 2005/05/06 02:55:27 vapier Exp $"; 38static const char *rcsid = "$Id: scanelf.c,v 1.47 2005/05/18 01:08:46 vapier Exp $";
39#define argv0 "scanelf" 39#define argv0 "scanelf"
40 40
41 41
42 42
43/* prototypes */ 43/* prototypes */
90} 90}
91static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro) 91static char *scanelf_file_stack(elfobj *elf, char *found_stack, char *found_relro)
92{ 92{
93 static char ret[8]; 93 static char ret[8];
94 char *found; 94 char *found;
95 int i, off, shown; 95 unsigned long i, off, shown;
96 96
97 if (!show_stack) return NULL; 97 if (!show_stack) return NULL;
98 98
99 shown = 0; 99 shown = 0;
100 strcpy(ret, "--- ---"); 100 strcpy(ret, "--- ---");
101
102 if (elf->phdr) {
101#define SHOW_STACK(B) \ 103#define SHOW_STACK(B) \
102 if (elf->elf_class == ELFCLASS ## B) { \ 104 if (elf->elf_class == ELFCLASS ## B) { \
103 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 105 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
104 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 106 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
105 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 107 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
118 ++shown; \ 120 ++shown; \
119 } \ 121 } \
120 } 122 }
121 SHOW_STACK(32) 123 SHOW_STACK(32)
122 SHOW_STACK(64) 124 SHOW_STACK(64)
125 }
126
123 if (be_quiet && !shown) 127 if (be_quiet && !shown)
124 return NULL; 128 return NULL;
125 else 129 else
126 return ret; 130 return ret;
127} 131}
128static char *scanelf_file_textrel(elfobj *elf, char *found_textrel) 132static char *scanelf_file_textrel(elfobj *elf, char *found_textrel)
129{ 133{
130 static char *ret = "TEXTREL"; 134 static char *ret = "TEXTREL";
131 int i; 135 unsigned long i;
132 136
133 if (!show_textrel) return NULL; 137 if (!show_textrel) return NULL;
134 138
139 if (elf->phdr) {
135#define SHOW_TEXTREL(B) \ 140#define SHOW_TEXTREL(B) \
136 if (elf->elf_class == ELFCLASS ## B) { \ 141 if (elf->elf_class == ELFCLASS ## B) { \
137 Elf ## B ## _Dyn *dyn; \ 142 Elf ## B ## _Dyn *dyn; \
138 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 143 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
139 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 144 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
145 Elf ## B ## _Off offset; \
140 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 146 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
141 if (phdr[i].p_type != PT_DYNAMIC) continue; \ 147 if (phdr[i].p_type != PT_DYNAMIC) continue; \
148 offset = EGET(phdr[i].p_offset); \
149 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
142 dyn = DYN ## B (elf->data + EGET(phdr[i].p_offset)); \ 150 dyn = DYN ## B (elf->data + offset); \
143 while (EGET(dyn->d_tag) != DT_NULL) { \ 151 while (EGET(dyn->d_tag) != DT_NULL) { \
144 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \ 152 if (EGET(dyn->d_tag) == DT_TEXTREL) { /*dyn->d_tag != DT_FLAGS)*/ \
145 *found_textrel = 1; \ 153 *found_textrel = 1; \
146 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \ 154 /*if (dyn->d_un.d_val & DF_TEXTREL)*/ \
147 return ret; \ 155 return ret; \
149 ++dyn; \ 157 ++dyn; \
150 } \ 158 } \
151 } } 159 } }
152 SHOW_TEXTREL(32) 160 SHOW_TEXTREL(32)
153 SHOW_TEXTREL(64) 161 SHOW_TEXTREL(64)
162 }
163
154 if (be_quiet) 164 if (be_quiet)
155 return NULL; 165 return NULL;
156 else 166 else
157 return " - "; 167 return " - ";
158} 168}
159static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len) 169static void scanelf_file_rpath(elfobj *elf, char *found_rpath, char **ret, size_t *ret_len)
160{ 170{
161 /* TODO: if be_quiet, only output RPATH's which aren't in /etc/ld.so.conf */ 171 /* TODO: if be_quiet, only output RPATH's which aren't in /etc/ld.so.conf */
162 int i; 172 unsigned long i;
163 char *rpath, *runpath; 173 char *rpath, *runpath;
164 void *strtbl_void; 174 void *strtbl_void;
165 175
166 if (!show_rpath) return; 176 if (!show_rpath) return;
167 177
168 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 178 strtbl_void = elf_findsecbyname(elf, ".dynstr");
169 rpath = runpath = NULL; 179 rpath = runpath = NULL;
170 180
171 if (strtbl_void) { 181 if (elf->phdr && strtbl_void) {
172#define SHOW_RPATH(B) \ 182#define SHOW_RPATH(B) \
173 if (elf->elf_class == ELFCLASS ## B) { \ 183 if (elf->elf_class == ELFCLASS ## B) { \
174 Elf ## B ## _Dyn *dyn; \ 184 Elf ## B ## _Dyn *dyn; \
175 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 185 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
176 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 186 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
177 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 187 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
188 Elf ## B ## _Off offset; \
178 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 189 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
179 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 190 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
191 offset = EGET(phdr[i].p_offset); \
192 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
180 dyn = DYN ## B (elf->data + EGET(phdr[i].p_offset)); \ 193 dyn = DYN ## B (elf->data + offset); \
181 while (EGET(dyn->d_tag) != DT_NULL) { \ 194 while (EGET(dyn->d_tag) != DT_NULL) { \
182 if (EGET(dyn->d_tag) == DT_RPATH) { \ 195 if (EGET(dyn->d_tag) == DT_RPATH) { \
183 if (rpath) warn("ELF has multiple DT_RPATH's !?"); \ 196 if (rpath) warn("ELF has multiple DT_RPATH's !?"); \
184 rpath = elf->data + EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 197 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
198 if (offset >= elf->len) continue; \
199 rpath = (char*)(elf->data + offset); \
185 *found_rpath = 1; \ 200 *found_rpath = 1; \
186 } else if (EGET(dyn->d_tag) == DT_RUNPATH) { \ 201 } else if (EGET(dyn->d_tag) == DT_RUNPATH) { \
187 if (runpath) warn("ELF has multiple DT_RUNPATH's !?"); \ 202 if (runpath) warn("ELF has multiple DT_RUNPATH's !?"); \
188 runpath = elf->data + EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 203 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
204 if (offset >= elf->len) continue; \
205 runpath = (char*)(elf->data + offset); \
189 *found_rpath = 1; \ 206 *found_rpath = 1; \
190 } \ 207 } \
191 ++dyn; \ 208 ++dyn; \
192 } \ 209 } \
193 } } 210 } }
211 else if (!be_quiet) 228 else if (!be_quiet)
212 xstrcat(ret, " - ", ret_len); 229 xstrcat(ret, " - ", ret_len);
213} 230}
214static void scanelf_file_needed(elfobj *elf, char *found_needed, char **ret, size_t *ret_len) 231static void scanelf_file_needed(elfobj *elf, char *found_needed, char **ret, size_t *ret_len)
215{ 232{
216 int i; 233 unsigned long i;
217 char *needed; 234 char *needed;
218 void *strtbl_void; 235 void *strtbl_void;
219 236
220 if (!show_needed) return; 237 if (!show_needed) return;
221 238
222 strtbl_void = elf_findsecbyname(elf, ".dynstr"); 239 strtbl_void = elf_findsecbyname(elf, ".dynstr");
223 240
224 if (strtbl_void) { 241 if (elf->phdr && strtbl_void) {
225#define SHOW_NEEDED(B) \ 242#define SHOW_NEEDED(B) \
226 if (elf->elf_class == ELFCLASS ## B) { \ 243 if (elf->elf_class == ELFCLASS ## B) { \
227 Elf ## B ## _Dyn *dyn; \ 244 Elf ## B ## _Dyn *dyn; \
228 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ 245 Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \
229 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \ 246 Elf ## B ## _Phdr *phdr = PHDR ## B (elf->phdr); \
230 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \ 247 Elf ## B ## _Shdr *strtbl = SHDR ## B (strtbl_void); \
248 Elf ## B ## _Off offset; \
231 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \ 249 for (i = 0; i < EGET(ehdr->e_phnum); i++) { \
232 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \ 250 if (EGET(phdr[i].p_type) != PT_DYNAMIC) continue; \
251 offset = EGET(phdr[i].p_offset); \
252 if (offset >= elf->len - sizeof(Elf ## B ## _Dyn)) continue; \
233 dyn = DYN ## B (elf->data + EGET(phdr[i].p_offset)); \ 253 dyn = DYN ## B (elf->data + offset); \
234 while (EGET(dyn->d_tag) != DT_NULL) { \ 254 while (EGET(dyn->d_tag) != DT_NULL) { \
235 if (EGET(dyn->d_tag) == DT_NEEDED) { \ 255 if (EGET(dyn->d_tag) == DT_NEEDED) { \
236 needed = elf->data + EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \ 256 offset = EGET(strtbl->sh_offset) + EGET(dyn->d_un.d_ptr); \
257 if (offset >= elf->len) continue; \
258 needed = (char*)(elf->data + offset); \
237 if (*found_needed) xchrcat(ret, ',', ret_len); \ 259 if (*found_needed) xchrcat(ret, ',', ret_len); \
238 xstrcat(ret, needed, ret_len); \ 260 xstrcat(ret, needed, ret_len); \
239 *found_needed = 1; \ 261 *found_needed = 1; \
240 } \ 262 } \
241 ++dyn; \ 263 ++dyn; \
265 } 287 }
266 return NULL; 288 return NULL;
267} 289}
268static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename) 290static char *scanelf_file_sym(elfobj *elf, char *found_sym, const char *filename)
269{ 291{
270 int i; 292 unsigned long i;
271 void *symtab_void, *strtab_void; 293 void *symtab_void, *strtab_void;
272 294
273 if (!find_sym) return NULL; 295 if (!find_sym) return NULL;
274 296
275 symtab_void = elf_findsecbyname(elf, ".symtab"); 297 symtab_void = elf_findsecbyname(elf, ".symtab");
279#define FIND_SYM(B) \ 301#define FIND_SYM(B) \
280 if (elf->elf_class == ELFCLASS ## B) { \ 302 if (elf->elf_class == ELFCLASS ## B) { \
281 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \ 303 Elf ## B ## _Shdr *symtab = SHDR ## B (symtab_void); \
282 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \ 304 Elf ## B ## _Shdr *strtab = SHDR ## B (strtab_void); \
283 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \ 305 Elf ## B ## _Sym *sym = SYM ## B (elf->data + EGET(symtab->sh_offset)); \
284 int cnt = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \ 306 unsigned long cnt = EGET(symtab->sh_size) / EGET(symtab->sh_entsize); \
285 char *symname; \ 307 char *symname; \
286 for (i = 0; i < cnt; ++i) { \ 308 for (i = 0; i < cnt; ++i) { \
287 if (sym->st_name) { \ 309 if (sym->st_name) { \
288 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ 310 symname = (char *)(elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \
289 if (*find_sym == '*') { \ 311 if (*find_sym == '*') { \
312} 334}
313/* scan an elf file and show all the fun stuff */ 335/* scan an elf file and show all the fun stuff */
314#define prints(str) fputs(str, stdout) 336#define prints(str) fputs(str, stdout)
315static void scanelf_file(const char *filename) 337static void scanelf_file(const char *filename)
316{ 338{
317 int i; 339 unsigned long i;
318 char found_pax, found_stack, found_relro, found_textrel, 340 char found_pax, found_stack, found_relro, found_textrel,
319 found_rpath, found_needed, found_interp, found_sym, 341 found_rpath, found_needed, found_interp, found_sym,
320 found_file; 342 found_file;
321 elfobj *elf; 343 elfobj *elf;
322 struct stat st; 344 struct stat st;
468 } 490 }
469 } 491 }
470 closedir(dir); 492 closedir(dir);
471} 493}
472 494
495static int scanelf_from_file(char *filename)
496{
497 FILE *fp = NULL;
498 char *p;
499 char path[_POSIX_PATH_MAX];
500
501 if (((strcmp(filename, "-")) == 0) && (ttyname(0) == NULL))
502 fp = stdin;
503 else if ((fp = fopen(filename, "r")) == NULL)
504 return 1;
505
506 while ((fgets(path, _POSIX_PATH_MAX, fp)) != NULL) {
507 if ((p = strchr(path, '\n')) != NULL)
508 *p = 0;
509 scanelf_dir(path);
510 }
511 if (fp != stdin)
512 fclose(fp);
513 return 0;
514}
515
473/* scan /etc/ld.so.conf for paths */ 516/* scan /etc/ld.so.conf for paths */
474static void scanelf_ldpath() 517static void scanelf_ldpath()
475{ 518{
476 char scan_l, scan_ul, scan_ull; 519 char scan_l, scan_ul, scan_ull;
477 char *path, *p; 520 char *path, *p;
521} 564}
522 565
523 566
524 567
525/* usage / invocation handling functions */ 568/* usage / invocation handling functions */
526#define PARSE_FLAGS "plRmyxetrnis:aqvF:o:BhV" 569#define PARSE_FLAGS "plRmyxetrnis:aqvF:f:o:BhV"
527#define a_argument required_argument 570#define a_argument required_argument
528static struct option const long_opts[] = { 571static struct option const long_opts[] = {
529 {"path", no_argument, NULL, 'p'}, 572 {"path", no_argument, NULL, 'p'},
530 {"ldpath", no_argument, NULL, 'l'}, 573 {"ldpath", no_argument, NULL, 'l'},
531 {"recursive", no_argument, NULL, 'R'}, 574 {"recursive", no_argument, NULL, 'R'},
540 {"symbol", a_argument, NULL, 's'}, 583 {"symbol", a_argument, NULL, 's'},
541 {"all", no_argument, NULL, 'a'}, 584 {"all", no_argument, NULL, 'a'},
542 {"quiet", no_argument, NULL, 'q'}, 585 {"quiet", no_argument, NULL, 'q'},
543 {"verbose", no_argument, NULL, 'v'}, 586 {"verbose", no_argument, NULL, 'v'},
544 {"format", a_argument, NULL, 'F'}, 587 {"format", a_argument, NULL, 'F'},
588 {"from", a_argument, NULL, 'f'},
545 {"file", a_argument, NULL, 'o'}, 589 {"file", a_argument, NULL, 'o'},
546 {"nobanner", no_argument, NULL, 'B'}, 590 {"nobanner", no_argument, NULL, 'B'},
547 {"help", no_argument, NULL, 'h'}, 591 {"help", no_argument, NULL, 'h'},
548 {"version", no_argument, NULL, 'V'}, 592 {"version", no_argument, NULL, 'V'},
549 {NULL, no_argument, NULL, 0x0} 593 {NULL, no_argument, NULL, 0x0}
559 "Print TEXTREL information", 603 "Print TEXTREL information",
560 "Print RPATH information", 604 "Print RPATH information",
561 "Print NEEDED information", 605 "Print NEEDED information",
562 "Print INTERP information", 606 "Print INTERP information",
563 "Find a specified symbol", 607 "Find a specified symbol",
564 "Print all scanned info (-x -e -t -r)\n", 608 "Print all scanned info (-x -e -t -r -n -i)\n",
565 "Only output 'bad' things", 609 "Only output 'bad' things",
566 "Be verbose (can be specified more than once)", 610 "Be verbose (can be specified more than once)",
567 "Use specified format for output", 611 "Use specified format for output",
612 "Read input stream from a filename",
568 "Write output stream to a filename", 613 "Write output stream to a filename",
569 "Don't display the header", 614 "Don't display the header",
570 "Print this help and exit", 615 "Print this help and exit",
571 "Print version and exit", 616 "Print version and exit",
572 NULL 617 NULL
573}; 618};
574 619
575/* display usage and exit */ 620/* display usage and exit */
576static void usage(int status) 621static void usage(int status)
577{ 622{
578 int i; 623 unsigned long i;
579 printf(" Scan ELF binaries for stuff\n\n" 624 printf(" Scan ELF binaries for stuff\n\n"
580 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0); 625 "Usage: %s [options] <dir1/file1> [dir2 dirN fileN ...]\n\n", argv0);
581 printf("Options: -[%s]\n", PARSE_FLAGS); 626 printf("Options: -[%s]\n", PARSE_FLAGS);
582 for (i = 0; long_opts[i].name; ++i) 627 for (i = 0; long_opts[i].name; ++i)
583 if (long_opts[i].has_arg == no_argument) 628 if (long_opts[i].has_arg == no_argument)
584 printf(" -%c, --%-13s %s\n", long_opts[i].val, 629 printf(" -%c, --%-13s %s\n", long_opts[i].val,
585 long_opts[i].name, opts_help[i]); 630 long_opts[i].name, opts_help[i]);
586 else 631 else
587 printf(" -%c, --%-6s <arg> %s\n", long_opts[i].val, 632 printf(" -%c, --%-6s <arg> %s\n", long_opts[i].val,
588 long_opts[i].name, opts_help[i]); 633 long_opts[i].name, opts_help[i]);
634
635 if (status != EXIT_SUCCESS)
636 exit(status);
637
638 puts("\nThe format modifiers for the -F option are:");
639 puts(" %F Filename \t%x PaX Flags \t%e STACK/RELRO");
640 puts(" %t TEXTREL \t%r RPATH \t%n NEEDED");
641 puts(" %i INTERP \t%s symbol");
642
589 exit(status); 643 exit(status);
590} 644}
591 645
592/* parse command line arguments and preform needed actions */ 646/* parse command line arguments and preform needed actions */
593static void parseargs(int argc, char *argv[]) 647static void parseargs(int argc, char *argv[])
594{ 648{
595 int flag; 649 int flag;
650 char *from_file = NULL;
596 651
597 opterr = 0; 652 opterr = 0;
598 while ((flag=getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) { 653 while ((flag=getopt_long(argc, argv, PARSE_FLAGS, long_opts, NULL)) != -1) {
599 switch (flag) { 654 switch (flag) {
600 655
603 "%s written for Gentoo Linux by <solar and vapier @ gentoo.org>\n", 658 "%s written for Gentoo Linux by <solar and vapier @ gentoo.org>\n",
604 __FILE__, __DATE__, rcsid, argv0); 659 __FILE__, __DATE__, rcsid, argv0);
605 exit(EXIT_SUCCESS); 660 exit(EXIT_SUCCESS);
606 break; 661 break;
607 case 'h': usage(EXIT_SUCCESS); break; 662 case 'h': usage(EXIT_SUCCESS); break;
608 663 case 'f':
664 if (from_file == NULL)
665 from_file = xstrdup(optarg);
666 break;
609 case 'o': { 667 case 'o': {
610 FILE *fp = NULL; 668 FILE *fp = NULL;
611 fp = freopen(optarg, "w", stdout); 669 fp = freopen(optarg, "w", stdout);
612 if (fp == NULL) 670 if (fp == NULL)
613 err("Could not open output stream '%s': %s", optarg, strerror(errno)); 671 err("Could not open output stream '%s': %s", optarg, strerror(errno));
623 sprintf(versioned_symname, "%s@", find_sym); 681 sprintf(versioned_symname, "%s@", find_sym);
624 break; 682 break;
625 } 683 }
626 684
627 case 'F': { 685 case 'F': {
628 out_format = strdup(optarg); 686 out_format = xstrdup(optarg);
629 break; 687 break;
630 } 688 }
631 689
632 case 'y': scan_symlink = 0; break; 690 case 'y': scan_symlink = 0; break;
633 case 'B': show_banner = 0; break; 691 case 'B': show_banner = 0; break;
702 if (be_verbose > 2) printf("Format: %s\n", out_format); 760 if (be_verbose > 2) printf("Format: %s\n", out_format);
703 761
704 /* now lets actually do the scanning */ 762 /* now lets actually do the scanning */
705 if (scan_ldpath) scanelf_ldpath(); 763 if (scan_ldpath) scanelf_ldpath();
706 if (scan_envpath) scanelf_envpath(); 764 if (scan_envpath) scanelf_envpath();
765 if (from_file) {
766 scanelf_from_file(from_file);
767 free(from_file);
768 from_file = *argv;
769 }
707 if (optind == argc && !scan_ldpath && !scan_envpath) 770 if (optind == argc && !scan_ldpath && !scan_envpath && !from_file)
708 err("Nothing to scan !?"); 771 err("Nothing to scan !?");
709 while (optind < argc) 772 while (optind < argc)
710 scanelf_dir(argv[optind++]); 773 scanelf_dir(argv[optind++]);
711 774
712 /* clean up */ 775 /* clean up */

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.47

  ViewVC Help
Powered by ViewVC 1.1.20