Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/elftoolchain/strings/strings.c
Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#include <libelf.h> | #include <libelf.h> | ||||
#include <libelftc.h> | #include <libelftc.h> | ||||
#include <gelf.h> | #include <gelf.h> | ||||
#include "_elftc.h" | #include "_elftc.h" | ||||
ELFTC_VCSID("$Id: strings.c 3446 2016-05-03 01:31:17Z emaste $"); | ELFTC_VCSID("$Id: strings.c 3446 2016-05-03 01:31:17Z emaste $"); | ||||
enum return_code { | |||||
RETURN_OK, | |||||
RETURN_NOINPUT, | |||||
RETURN_SOFTWARE | |||||
}; | |||||
enum radix_style { | enum radix_style { | ||||
RADIX_DECIMAL, | RADIX_DECIMAL, | ||||
RADIX_HEX, | RADIX_HEX, | ||||
RADIX_OCTAL | RADIX_OCTAL | ||||
}; | }; | ||||
enum encoding_style { | enum encoding_style { | ||||
ENCODING_7BIT, | ENCODING_7BIT, | ||||
Show All 37 Lines | |||||
* strings(1) extracts text(contiguous printable characters) | * strings(1) extracts text(contiguous printable characters) | ||||
* from elf and binary files. | * from elf and binary files. | ||||
*/ | */ | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
int ch, rc; | int ch, rc; | ||||
rc = RETURN_OK; | rc = 0; | ||||
min_len = 0; | min_len = 0; | ||||
encoding_size = 1; | encoding_size = 1; | ||||
if (elf_version(EV_CURRENT) == EV_NONE) | if (elf_version(EV_CURRENT) == EV_NONE) | ||||
errx(EXIT_FAILURE, "ELF library initialization failed: %s", | errx(EXIT_FAILURE, "ELF library initialization failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", | while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", | ||||
strings_longopts, NULL)) != -1) | strings_longopts, NULL)) != -1) | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | main(int argc, char **argv) | ||||
argc -= optind; | argc -= optind; | ||||
argv += optind; | argv += optind; | ||||
if (!min_len) | if (!min_len) | ||||
min_len = 4; | min_len = 4; | ||||
if (!*argv) | if (!*argv) | ||||
rc = handle_file("{standard input}"); | rc = handle_file("{standard input}"); | ||||
else while (*argv) { | else while (*argv) { | ||||
rc = handle_file(*argv); | if (handle_file(*argv) != 0) | ||||
rc = 1; | |||||
argv++; | argv++; | ||||
} | } | ||||
return (rc); | return (rc); | ||||
} | } | ||||
int | int | ||||
handle_file(const char *name) | handle_file(const char *name) | ||||
{ | { | ||||
int fd, rt; | int fd, rt; | ||||
if (name == NULL) | if (name == NULL) | ||||
return (RETURN_NOINPUT); | return (1); | ||||
if (strcmp("{standard input}", name) != 0) { | if (strcmp("{standard input}", name) != 0) { | ||||
if (freopen(name, "rb", stdin) == NULL) { | if (freopen(name, "rb", stdin) == NULL) { | ||||
warnx("'%s': %s", name, strerror(errno)); | warnx("'%s': %s", name, strerror(errno)); | ||||
return (RETURN_NOINPUT); | return (1); | ||||
} | } | ||||
} else { | } else { | ||||
return (find_strings(name, (off_t)0, (off_t)0)); | return (find_strings(name, (off_t)0, (off_t)0)); | ||||
} | } | ||||
fd = fileno(stdin); | fd = fileno(stdin); | ||||
if (fd < 0) | if (fd < 0) | ||||
return (RETURN_NOINPUT); | return (1); | ||||
rt = handle_elf(name, fd); | rt = handle_elf(name, fd); | ||||
return (rt); | return (rt); | ||||
} | } | ||||
/* | /* | ||||
* Files not understood by handle_elf, will be passed off here and will | * Files not understood by handle_elf, will be passed off here and will | ||||
* treated as a binary file. This would include text file, core dumps ... | * treated as a binary file. This would include text file, core dumps ... | ||||
*/ | */ | ||||
int | int | ||||
handle_binary(const char *name, int fd) | handle_binary(const char *name, int fd) | ||||
{ | { | ||||
struct stat buf; | struct stat buf; | ||||
memset(&buf, 0, sizeof(struct stat)); | memset(&buf, 0, sizeof(struct stat)); | ||||
(void) lseek(fd, (off_t)0, SEEK_SET); | (void) lseek(fd, (off_t)0, SEEK_SET); | ||||
if (!fstat(fd, &buf)) | if (!fstat(fd, &buf)) | ||||
return (find_strings(name, (off_t)0, buf.st_size)); | return (find_strings(name, (off_t)0, buf.st_size)); | ||||
return (RETURN_SOFTWARE); | return (1); | ||||
} | } | ||||
/* | /* | ||||
* Will analyse a file to see if it ELF, other files including ar(1), | * Will analyse a file to see if it ELF, other files including ar(1), | ||||
* core dumps are passed off and treated as flat binary files. Unlike | * core dumps are passed off and treated as flat binary files. Unlike | ||||
* GNU size in FreeBSD this routine will not treat ELF object from | * GNU size in FreeBSD this routine will not treat ELF object from | ||||
* different archs as flat binary files(has to overridden using -a). | * different archs as flat binary files(has to overridden using -a). | ||||
*/ | */ | ||||
int | int | ||||
handle_elf(const char *name, int fd) | handle_elf(const char *name, int fd) | ||||
{ | { | ||||
GElf_Ehdr elfhdr; | GElf_Ehdr elfhdr; | ||||
GElf_Shdr shdr; | GElf_Shdr shdr; | ||||
Elf *elf; | Elf *elf; | ||||
Elf_Scn *scn; | Elf_Scn *scn; | ||||
int rc; | int rc; | ||||
rc = RETURN_OK; | rc = 0; | ||||
/* If entire file is chosen, treat it as a binary file */ | /* If entire file is chosen, treat it as a binary file */ | ||||
if (entire_file) | if (entire_file) | ||||
return (handle_binary(name, fd)); | return (handle_binary(name, fd)); | ||||
(void) lseek(fd, (off_t)0, SEEK_SET); | (void) lseek(fd, (off_t)0, SEEK_SET); | ||||
elf = elf_begin(fd, ELF_C_READ, NULL); | elf = elf_begin(fd, ELF_C_READ, NULL); | ||||
if (elf_kind(elf) != ELF_K_ELF) { | if (elf_kind(elf) != ELF_K_ELF) { | ||||
(void) elf_end(elf); | (void) elf_end(elf); | ||||
return (handle_binary(name, fd)); | return (handle_binary(name, fd)); | ||||
} | } | ||||
if (gelf_getehdr(elf, &elfhdr) == NULL) { | if (gelf_getehdr(elf, &elfhdr) == NULL) { | ||||
(void) elf_end(elf); | (void) elf_end(elf); | ||||
warnx("%s: ELF file could not be processed", name); | warnx("%s: ELF file could not be processed", name); | ||||
return (RETURN_SOFTWARE); | return (1); | ||||
} | } | ||||
if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { | if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { | ||||
(void) elf_end(elf); | (void) elf_end(elf); | ||||
return (handle_binary(name, fd)); | return (handle_binary(name, fd)); | ||||
} else { | } else { | ||||
scn = NULL; | scn = NULL; | ||||
while ((scn = elf_nextscn(elf, scn)) != NULL) { | while ((scn = elf_nextscn(elf, scn)) != NULL) { | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | find_strings(const char *name, off_t offset, off_t size) | ||||
off_t cur_off, start_off; | off_t cur_off, start_off; | ||||
char *obuf; | char *obuf; | ||||
long c; | long c; | ||||
int i; | int i; | ||||
if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { | if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { | ||||
(void) fprintf(stderr, "Unable to allocate memory: %s\n", | (void) fprintf(stderr, "Unable to allocate memory: %s\n", | ||||
strerror(errno)); | strerror(errno)); | ||||
return (RETURN_SOFTWARE); | return (1); | ||||
} | } | ||||
(void) fseeko(stdin, offset, SEEK_SET); | (void) fseeko(stdin, offset, SEEK_SET); | ||||
cur_off = offset; | cur_off = offset; | ||||
start_off = 0; | start_off = 0; | ||||
while(1) { | while(1) { | ||||
if ((offset + size) && (cur_off >= offset + size)) | if ((offset + size) && (cur_off >= offset + size)) | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | if (i >= min_len && ((cur_off <= offset + size) || | ||||
break; | break; | ||||
putchar(c); | putchar(c); | ||||
} | } | ||||
putchar('\n'); | putchar('\n'); | ||||
} | } | ||||
} | } | ||||
_exit1: | _exit1: | ||||
free(obuf); | free(obuf); | ||||
return (RETURN_OK); | return (0); | ||||
} | } | ||||
#define USAGE_MESSAGE "\ | #define USAGE_MESSAGE "\ | ||||
Usage: %s [options] [file...]\n\ | Usage: %s [options] [file...]\n\ | ||||
Print contiguous sequences of printable characters.\n\n\ | Print contiguous sequences of printable characters.\n\n\ | ||||
Options:\n\ | Options:\n\ | ||||
-a | --all Scan the entire file for strings.\n\ | -a | --all Scan the entire file for strings.\n\ | ||||
-e ENC | --encoding=ENC Select the character encoding to use.\n\ | -e ENC | --encoding=ENC Select the character encoding to use.\n\ | ||||
Show All 20 Lines |