1a85fe12eSEd Maste /*- 2a85fe12eSEd Maste * Copyright (c) 2007 S.Sam Arun Raj 3a85fe12eSEd Maste * All rights reserved. 4a85fe12eSEd Maste * 5a85fe12eSEd Maste * Redistribution and use in source and binary forms, with or without 6a85fe12eSEd Maste * modification, are permitted provided that the following conditions 7a85fe12eSEd Maste * are met: 8a85fe12eSEd Maste * 1. Redistributions of source code must retain the above copyright 9a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer. 10a85fe12eSEd Maste * 2. Redistributions in binary form must reproduce the above copyright 11a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer in the 12a85fe12eSEd Maste * documentation and/or other materials provided with the distribution. 13a85fe12eSEd Maste * 14a85fe12eSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15a85fe12eSEd Maste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16a85fe12eSEd Maste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17a85fe12eSEd Maste * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18a85fe12eSEd Maste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19a85fe12eSEd Maste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20a85fe12eSEd Maste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21a85fe12eSEd Maste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22a85fe12eSEd Maste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23a85fe12eSEd Maste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24a85fe12eSEd Maste * SUCH DAMAGE. 25a85fe12eSEd Maste */ 26a85fe12eSEd Maste 27a85fe12eSEd Maste #include <sys/types.h> 286d395debSMariusz Zaborski #include <sys/capsicum.h> 294f486ad6SMariusz Zaborski #include <sys/stat.h> 30a85fe12eSEd Maste 316d395debSMariusz Zaborski #include <capsicum_helpers.h> 32a85fe12eSEd Maste #include <ctype.h> 33a85fe12eSEd Maste #include <err.h> 34a85fe12eSEd Maste #include <errno.h> 35a85fe12eSEd Maste #include <fcntl.h> 36a85fe12eSEd Maste #include <getopt.h> 37a85fe12eSEd Maste #include <inttypes.h> 38a85fe12eSEd Maste #include <stdint.h> 39a85fe12eSEd Maste #include <stdio.h> 40a85fe12eSEd Maste #include <stdlib.h> 41a85fe12eSEd Maste #include <string.h> 42839529caSEd Maste #include <sysexits.h> 43a85fe12eSEd Maste #include <unistd.h> 44a85fe12eSEd Maste 45a85fe12eSEd Maste #include <libelf.h> 46a85fe12eSEd Maste #include <libelftc.h> 47a85fe12eSEd Maste #include <gelf.h> 48a85fe12eSEd Maste 496d395debSMariusz Zaborski #include <libcasper.h> 506d395debSMariusz Zaborski #include <casper/cap_fileargs.h> 516d395debSMariusz Zaborski 52a85fe12eSEd Maste #include "_elftc.h" 53a85fe12eSEd Maste 54ae500c1fSEd Maste ELFTC_VCSID("$Id: strings.c 3648 2018-11-22 23:26:43Z emaste $"); 55a85fe12eSEd Maste 56a85fe12eSEd Maste enum radix_style { 57a85fe12eSEd Maste RADIX_DECIMAL, 58a85fe12eSEd Maste RADIX_HEX, 59a85fe12eSEd Maste RADIX_OCTAL 60a85fe12eSEd Maste }; 61a85fe12eSEd Maste 62a85fe12eSEd Maste enum encoding_style { 63a85fe12eSEd Maste ENCODING_7BIT, 64a85fe12eSEd Maste ENCODING_8BIT, 65a85fe12eSEd Maste ENCODING_16BIT_BIG, 66a85fe12eSEd Maste ENCODING_16BIT_LITTLE, 67a85fe12eSEd Maste ENCODING_32BIT_BIG, 68a85fe12eSEd Maste ENCODING_32BIT_LITTLE 69a85fe12eSEd Maste }; 70a85fe12eSEd Maste 71a85fe12eSEd Maste #define PRINTABLE(c) \ 72a85fe12eSEd Maste ((c) >= 0 && (c) <= 255 && \ 73a85fe12eSEd Maste ((c) == '\t' || isprint((c)) || \ 74a85fe12eSEd Maste (encoding == ENCODING_8BIT && (c) > 127))) 75a85fe12eSEd Maste 76839529caSEd Maste static int encoding_size, entire_file, show_filename, show_loc; 7750f69bfbSEd Maste static enum encoding_style encoding; 7850f69bfbSEd Maste static enum radix_style radix; 79839529caSEd Maste static intmax_t min_len; 80a85fe12eSEd Maste 81a85fe12eSEd Maste static struct option strings_longopts[] = { 82a85fe12eSEd Maste { "all", no_argument, NULL, 'a'}, 83a85fe12eSEd Maste { "bytes", required_argument, NULL, 'n'}, 84a85fe12eSEd Maste { "encoding", required_argument, NULL, 'e'}, 85a85fe12eSEd Maste { "help", no_argument, NULL, 'h'}, 86a85fe12eSEd Maste { "print-file-name", no_argument, NULL, 'f'}, 87a85fe12eSEd Maste { "radix", required_argument, NULL, 't'}, 88a85fe12eSEd Maste { "version", no_argument, NULL, 'v'}, 89a85fe12eSEd Maste { NULL, 0, NULL, 0 } 90a85fe12eSEd Maste }; 91a85fe12eSEd Maste 9255d3f888SMariusz Zaborski int getcharacter(FILE *, long *); 936d395debSMariusz Zaborski int handle_file(fileargs_t *fa, const char *); 9461d994f1SMariusz Zaborski int handle_elf(const char *, FILE *); 9561d994f1SMariusz Zaborski int handle_binary(const char *, FILE *, size_t); 9661d994f1SMariusz Zaborski int find_strings(const char *, FILE *, off_t, off_t); 97a85fe12eSEd Maste void show_version(void); 98a85fe12eSEd Maste void usage(void); 99a85fe12eSEd Maste 100a85fe12eSEd Maste /* 101a85fe12eSEd Maste * strings(1) extracts text(contiguous printable characters) 102a85fe12eSEd Maste * from elf and binary files. 103a85fe12eSEd Maste */ 104a85fe12eSEd Maste int 105a85fe12eSEd Maste main(int argc, char **argv) 106a85fe12eSEd Maste { 1076d395debSMariusz Zaborski fileargs_t *fa; 1086d395debSMariusz Zaborski cap_rights_t rights; 109a85fe12eSEd Maste int ch, rc; 110a85fe12eSEd Maste 111f8d647b4SEd Maste rc = 0; 112a85fe12eSEd Maste min_len = 0; 113a85fe12eSEd Maste encoding_size = 1; 114a85fe12eSEd Maste if (elf_version(EV_CURRENT) == EV_NONE) 115a85fe12eSEd Maste errx(EXIT_FAILURE, "ELF library initialization failed: %s", 116a85fe12eSEd Maste elf_errmsg(-1)); 117a85fe12eSEd Maste 118a85fe12eSEd Maste while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", 1194f486ad6SMariusz Zaborski strings_longopts, NULL)) != -1) { 120a85fe12eSEd Maste switch ((char)ch) { 121a85fe12eSEd Maste case 'a': 122a85fe12eSEd Maste entire_file = 1; 123a85fe12eSEd Maste break; 124a85fe12eSEd Maste case 'e': 125a85fe12eSEd Maste if (*optarg == 's') { 126a85fe12eSEd Maste encoding = ENCODING_7BIT; 127a85fe12eSEd Maste } else if (*optarg == 'S') { 128a85fe12eSEd Maste encoding = ENCODING_8BIT; 129a85fe12eSEd Maste } else if (*optarg == 'b') { 130a85fe12eSEd Maste encoding = ENCODING_16BIT_BIG; 131a85fe12eSEd Maste encoding_size = 2; 132a85fe12eSEd Maste } else if (*optarg == 'B') { 133a85fe12eSEd Maste encoding = ENCODING_32BIT_BIG; 134a85fe12eSEd Maste encoding_size = 4; 135a85fe12eSEd Maste } else if (*optarg == 'l') { 136a85fe12eSEd Maste encoding = ENCODING_16BIT_LITTLE; 137a85fe12eSEd Maste encoding_size = 2; 138a85fe12eSEd Maste } else if (*optarg == 'L') { 139a85fe12eSEd Maste encoding = ENCODING_32BIT_LITTLE; 140a85fe12eSEd Maste encoding_size = 4; 141a85fe12eSEd Maste } else 142a85fe12eSEd Maste usage(); 143a85fe12eSEd Maste /* NOTREACHED */ 144a85fe12eSEd Maste break; 145a85fe12eSEd Maste case 'f': 146a85fe12eSEd Maste show_filename = 1; 147a85fe12eSEd Maste break; 148a85fe12eSEd Maste case 'n': 149839529caSEd Maste min_len = strtoimax(optarg, (char**)NULL, 10); 150839529caSEd Maste if (min_len <= 0) 151839529caSEd Maste errx(EX_USAGE, "option -n should specify a " 152839529caSEd Maste "positive decimal integer."); 153a85fe12eSEd Maste break; 154a85fe12eSEd Maste case 'o': 155a85fe12eSEd Maste show_loc = 1; 156a85fe12eSEd Maste radix = RADIX_OCTAL; 157a85fe12eSEd Maste break; 158a85fe12eSEd Maste case 't': 159a85fe12eSEd Maste show_loc = 1; 160a85fe12eSEd Maste if (*optarg == 'd') 161a85fe12eSEd Maste radix = RADIX_DECIMAL; 162a85fe12eSEd Maste else if (*optarg == 'o') 163a85fe12eSEd Maste radix = RADIX_OCTAL; 164a85fe12eSEd Maste else if (*optarg == 'x') 165a85fe12eSEd Maste radix = RADIX_HEX; 166a85fe12eSEd Maste else 167a85fe12eSEd Maste usage(); 168a85fe12eSEd Maste /* NOTREACHED */ 169a85fe12eSEd Maste break; 170a85fe12eSEd Maste case 'v': 171a85fe12eSEd Maste case 'V': 172a85fe12eSEd Maste show_version(); 173a85fe12eSEd Maste /* NOTREACHED */ 174a85fe12eSEd Maste case '0': 175a85fe12eSEd Maste case '1': 176a85fe12eSEd Maste case '2': 177a85fe12eSEd Maste case '3': 178a85fe12eSEd Maste case '4': 179a85fe12eSEd Maste case '5': 180a85fe12eSEd Maste case '6': 181a85fe12eSEd Maste case '7': 182a85fe12eSEd Maste case '8': 183a85fe12eSEd Maste case '9': 184a85fe12eSEd Maste min_len *= 10; 185a85fe12eSEd Maste min_len += ch - '0'; 186a85fe12eSEd Maste break; 187a85fe12eSEd Maste case 'h': 188a85fe12eSEd Maste case '?': 189a85fe12eSEd Maste default: 190a85fe12eSEd Maste usage(); 191a85fe12eSEd Maste /* NOTREACHED */ 192a85fe12eSEd Maste } 1934f486ad6SMariusz Zaborski } 194a85fe12eSEd Maste argc -= optind; 195a85fe12eSEd Maste argv += optind; 196a85fe12eSEd Maste 1976d395debSMariusz Zaborski cap_rights_init(&rights, CAP_READ, CAP_SEEK, CAP_FSTAT, CAP_FCNTL); 198d76eef34SEd Maste fa = fileargs_init(argc, argv, O_RDONLY, 0, &rights, FA_OPEN); 1996d395debSMariusz Zaborski if (fa == NULL) 2006d395debSMariusz Zaborski err(1, "Unable to initialize casper fileargs"); 2016d395debSMariusz Zaborski 2026d395debSMariusz Zaborski caph_cache_catpages(); 203*5ff84ed3SMariusz Zaborski if (caph_limit_stdio() < 0 || caph_enter_casper() < 0) { 2046d395debSMariusz Zaborski fileargs_free(fa); 2056d395debSMariusz Zaborski err(1, "Unable to enter capability mode"); 2066d395debSMariusz Zaborski } 2076d395debSMariusz Zaborski 2084f486ad6SMariusz Zaborski if (min_len == 0) 209a85fe12eSEd Maste min_len = 4; 2104f486ad6SMariusz Zaborski if (*argv == NULL) 21161d994f1SMariusz Zaborski rc = find_strings("{standard input}", stdin, 0, 0); 2124f486ad6SMariusz Zaborski else while (*argv != NULL) { 2136d395debSMariusz Zaborski if (handle_file(fa, *argv) != 0) 214f8d647b4SEd Maste rc = 1; 215a85fe12eSEd Maste argv++; 216a85fe12eSEd Maste } 2176d395debSMariusz Zaborski 2186d395debSMariusz Zaborski fileargs_free(fa); 2196d395debSMariusz Zaborski 220a85fe12eSEd Maste return (rc); 221a85fe12eSEd Maste } 222a85fe12eSEd Maste 223a85fe12eSEd Maste int 2246d395debSMariusz Zaborski handle_file(fileargs_t *fa, const char *name) 225a85fe12eSEd Maste { 22661d994f1SMariusz Zaborski FILE *pfile; 22761d994f1SMariusz Zaborski int rt; 228a85fe12eSEd Maste 229a85fe12eSEd Maste if (name == NULL) 230f8d647b4SEd Maste return (1); 2316d395debSMariusz Zaborski pfile = fileargs_fopen(fa, name, "rb"); 23261d994f1SMariusz Zaborski if (pfile == NULL) { 233a85fe12eSEd Maste warnx("'%s': %s", name, strerror(errno)); 234f8d647b4SEd Maste return (1); 235a85fe12eSEd Maste } 236a85fe12eSEd Maste 23761d994f1SMariusz Zaborski rt = handle_elf(name, pfile); 23861d994f1SMariusz Zaborski fclose(pfile); 239a85fe12eSEd Maste return (rt); 240a85fe12eSEd Maste } 241a85fe12eSEd Maste 242a85fe12eSEd Maste /* 243a85fe12eSEd Maste * Files not understood by handle_elf, will be passed off here and will 244a85fe12eSEd Maste * treated as a binary file. This would include text file, core dumps ... 245a85fe12eSEd Maste */ 246a85fe12eSEd Maste int 24761d994f1SMariusz Zaborski handle_binary(const char *name, FILE *pfile, size_t size) 248a85fe12eSEd Maste { 249a85fe12eSEd Maste 25061d994f1SMariusz Zaborski (void)fseeko(pfile, 0, SEEK_SET); 25161d994f1SMariusz Zaborski return (find_strings(name, pfile, 0, size)); 252a85fe12eSEd Maste } 253a85fe12eSEd Maste 254a85fe12eSEd Maste /* 255a85fe12eSEd Maste * Will analyse a file to see if it ELF, other files including ar(1), 256a85fe12eSEd Maste * core dumps are passed off and treated as flat binary files. Unlike 257a85fe12eSEd Maste * GNU size in FreeBSD this routine will not treat ELF object from 258a85fe12eSEd Maste * different archs as flat binary files(has to overridden using -a). 259a85fe12eSEd Maste */ 260a85fe12eSEd Maste int 26161d994f1SMariusz Zaborski handle_elf(const char *name, FILE *pfile) 262a85fe12eSEd Maste { 26361d994f1SMariusz Zaborski struct stat buf; 264a85fe12eSEd Maste GElf_Ehdr elfhdr; 265a85fe12eSEd Maste GElf_Shdr shdr; 266a85fe12eSEd Maste Elf *elf; 267a85fe12eSEd Maste Elf_Scn *scn; 26861d994f1SMariusz Zaborski int rc, fd; 269a85fe12eSEd Maste 270f8d647b4SEd Maste rc = 0; 27161d994f1SMariusz Zaborski fd = fileno(pfile); 27261d994f1SMariusz Zaborski if (fstat(fd, &buf) < 0) 27361d994f1SMariusz Zaborski return (1); 27461d994f1SMariusz Zaborski 275b6b6f9ccSEd Maste /* If entire file is chosen, treat it as a binary file */ 276a85fe12eSEd Maste if (entire_file) 27761d994f1SMariusz Zaborski return (handle_binary(name, pfile, buf.st_size)); 278a85fe12eSEd Maste 2794f486ad6SMariusz Zaborski (void)lseek(fd, 0, SEEK_SET); 280a85fe12eSEd Maste elf = elf_begin(fd, ELF_C_READ, NULL); 281a85fe12eSEd Maste if (elf_kind(elf) != ELF_K_ELF) { 282a85fe12eSEd Maste (void)elf_end(elf); 28361d994f1SMariusz Zaborski return (handle_binary(name, pfile, buf.st_size)); 284a85fe12eSEd Maste } 285a85fe12eSEd Maste 286a85fe12eSEd Maste if (gelf_getehdr(elf, &elfhdr) == NULL) { 287a85fe12eSEd Maste (void)elf_end(elf); 288a85fe12eSEd Maste warnx("%s: ELF file could not be processed", name); 289f8d647b4SEd Maste return (1); 290a85fe12eSEd Maste } 291a85fe12eSEd Maste 292a85fe12eSEd Maste if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { 293a85fe12eSEd Maste (void)elf_end(elf); 29461d994f1SMariusz Zaborski return (handle_binary(name, pfile, buf.st_size)); 295a85fe12eSEd Maste } else { 296a85fe12eSEd Maste scn = NULL; 297a85fe12eSEd Maste while ((scn = elf_nextscn(elf, scn)) != NULL) { 298a85fe12eSEd Maste if (gelf_getshdr(scn, &shdr) == NULL) 299a85fe12eSEd Maste continue; 300a85fe12eSEd Maste if (shdr.sh_type != SHT_NOBITS && 301a85fe12eSEd Maste (shdr.sh_flags & SHF_ALLOC) != 0) { 30261d994f1SMariusz Zaborski rc = find_strings(name, pfile, shdr.sh_offset, 303a85fe12eSEd Maste shdr.sh_size); 304a85fe12eSEd Maste } 305a85fe12eSEd Maste } 306a85fe12eSEd Maste } 307a85fe12eSEd Maste (void)elf_end(elf); 308a85fe12eSEd Maste return (rc); 309a85fe12eSEd Maste } 310a85fe12eSEd Maste 311a85fe12eSEd Maste /* 312a85fe12eSEd Maste * Retrieves a character from input stream based on the encoding 313a85fe12eSEd Maste * type requested. 314a85fe12eSEd Maste */ 31555d3f888SMariusz Zaborski int 31655d3f888SMariusz Zaborski getcharacter(FILE *pfile, long *rt) 317a85fe12eSEd Maste { 318cee114a8SMariusz Zaborski int i, c; 319cee114a8SMariusz Zaborski char buf[4]; 320a85fe12eSEd Maste 321a85fe12eSEd Maste for(i = 0; i < encoding_size; i++) { 32261d994f1SMariusz Zaborski c = getc(pfile); 3234cb07cbaSMariusz Zaborski if (c == EOF) 32455d3f888SMariusz Zaborski return (-1); 325a85fe12eSEd Maste buf[i] = c; 326a85fe12eSEd Maste } 327a85fe12eSEd Maste 328a85fe12eSEd Maste switch (encoding) { 329a85fe12eSEd Maste case ENCODING_7BIT: 330a85fe12eSEd Maste case ENCODING_8BIT: 33155d3f888SMariusz Zaborski *rt = buf[0]; 332a85fe12eSEd Maste break; 333a85fe12eSEd Maste case ENCODING_16BIT_BIG: 33455d3f888SMariusz Zaborski *rt = (buf[0] << 8) | buf[1]; 335a85fe12eSEd Maste break; 336a85fe12eSEd Maste case ENCODING_16BIT_LITTLE: 33755d3f888SMariusz Zaborski *rt = buf[0] | (buf[1] << 8); 338a85fe12eSEd Maste break; 339a85fe12eSEd Maste case ENCODING_32BIT_BIG: 34055d3f888SMariusz Zaborski *rt = ((long) buf[0] << 24) | ((long) buf[1] << 16) | 341a85fe12eSEd Maste ((long) buf[2] << 8) | buf[3]; 342a85fe12eSEd Maste break; 343a85fe12eSEd Maste case ENCODING_32BIT_LITTLE: 34455d3f888SMariusz Zaborski *rt = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | 345a85fe12eSEd Maste ((long) buf[3] << 24); 346a85fe12eSEd Maste break; 34755d3f888SMariusz Zaborski default: 34855d3f888SMariusz Zaborski return (-1); 349a85fe12eSEd Maste } 35055d3f888SMariusz Zaborski 35155d3f888SMariusz Zaborski return (0); 352a85fe12eSEd Maste } 353a85fe12eSEd Maste 354a85fe12eSEd Maste /* 35561d994f1SMariusz Zaborski * Input stream is read until the end of file is reached or until 356a85fe12eSEd Maste * the section size is reached in case of ELF files. Contiguous 357a85fe12eSEd Maste * characters of >= min_size(default 4) will be displayed. 358a85fe12eSEd Maste */ 359a85fe12eSEd Maste int 36061d994f1SMariusz Zaborski find_strings(const char *name, FILE *pfile, off_t offset, off_t size) 361a85fe12eSEd Maste { 362a85fe12eSEd Maste off_t cur_off, start_off; 363a85fe12eSEd Maste char *obuf; 364a85fe12eSEd Maste long c; 365a85fe12eSEd Maste int i; 366a85fe12eSEd Maste 367a85fe12eSEd Maste if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { 3684f486ad6SMariusz Zaborski fprintf(stderr, "Unable to allocate memory: %s\n", 369a85fe12eSEd Maste strerror(errno)); 370f8d647b4SEd Maste return (1); 371a85fe12eSEd Maste } 372a85fe12eSEd Maste 37361d994f1SMariusz Zaborski (void)fseeko(pfile, offset, SEEK_SET); 374a85fe12eSEd Maste cur_off = offset; 375a85fe12eSEd Maste start_off = 0; 376248b5d08SMateusz Guzik for (;;) { 377a85fe12eSEd Maste if ((offset + size) && (cur_off >= offset + size)) 378a85fe12eSEd Maste break; 379a85fe12eSEd Maste start_off = cur_off; 380a85fe12eSEd Maste memset(obuf, 0, min_len + 1); 381a85fe12eSEd Maste for(i = 0; i < min_len; i++) { 38255d3f888SMariusz Zaborski if (getcharacter(pfile, &c) < 0) 383a85fe12eSEd Maste goto _exit1; 384a85fe12eSEd Maste if (PRINTABLE(c)) { 385a85fe12eSEd Maste obuf[i] = c; 386a85fe12eSEd Maste obuf[i + 1] = 0; 387a85fe12eSEd Maste cur_off += encoding_size; 388a85fe12eSEd Maste } else { 389a85fe12eSEd Maste if (encoding == ENCODING_8BIT && 390a85fe12eSEd Maste (uint8_t)c > 127) { 391a85fe12eSEd Maste obuf[i] = c; 392a85fe12eSEd Maste obuf[i + 1] = 0; 393a85fe12eSEd Maste cur_off += encoding_size; 394a85fe12eSEd Maste continue; 395a85fe12eSEd Maste } 396a85fe12eSEd Maste cur_off += encoding_size; 397a85fe12eSEd Maste break; 398a85fe12eSEd Maste } 399a85fe12eSEd Maste } 400a85fe12eSEd Maste 401a85fe12eSEd Maste if (i >= min_len && ((cur_off <= offset + size) || 402a85fe12eSEd Maste !(offset + size))) { 403a85fe12eSEd Maste if (show_filename) 404a85fe12eSEd Maste printf("%s: ", name); 405a85fe12eSEd Maste if (show_loc) { 406a85fe12eSEd Maste switch (radix) { 407a85fe12eSEd Maste case RADIX_DECIMAL: 4084f486ad6SMariusz Zaborski printf("%7ju ", (uintmax_t)start_off); 409a85fe12eSEd Maste break; 410a85fe12eSEd Maste case RADIX_HEX: 4114f486ad6SMariusz Zaborski printf("%7jx ", (uintmax_t)start_off); 412a85fe12eSEd Maste break; 413a85fe12eSEd Maste case RADIX_OCTAL: 4144f486ad6SMariusz Zaborski printf("%7jo ", (uintmax_t)start_off); 415a85fe12eSEd Maste break; 416a85fe12eSEd Maste } 417a85fe12eSEd Maste } 418a85fe12eSEd Maste printf("%s", obuf); 419a85fe12eSEd Maste 420248b5d08SMateusz Guzik for (;;) { 421a85fe12eSEd Maste if ((offset + size) && 422a85fe12eSEd Maste (cur_off >= offset + size)) 423a85fe12eSEd Maste break; 42455d3f888SMariusz Zaborski if (getcharacter(pfile, &c) < 0) 4251194c3cbSMariusz Zaborski break; 42655d3f888SMariusz Zaborski cur_off += encoding_size; 427a85fe12eSEd Maste if (encoding == ENCODING_8BIT && 428a85fe12eSEd Maste (uint8_t)c > 127) { 429a85fe12eSEd Maste putchar(c); 430a85fe12eSEd Maste continue; 431a85fe12eSEd Maste } 43255d3f888SMariusz Zaborski if (!PRINTABLE(c)) 43355d3f888SMariusz Zaborski break; 434a85fe12eSEd Maste putchar(c); 435a85fe12eSEd Maste } 436a85fe12eSEd Maste putchar('\n'); 437a85fe12eSEd Maste } 438a85fe12eSEd Maste } 439a85fe12eSEd Maste _exit1: 440a85fe12eSEd Maste free(obuf); 441f8d647b4SEd Maste return (0); 442a85fe12eSEd Maste } 443a85fe12eSEd Maste 444a85fe12eSEd Maste #define USAGE_MESSAGE "\ 445a85fe12eSEd Maste Usage: %s [options] [file...]\n\ 446a85fe12eSEd Maste Print contiguous sequences of printable characters.\n\n\ 447a85fe12eSEd Maste Options:\n\ 448a85fe12eSEd Maste -a | --all Scan the entire file for strings.\n\ 449a85fe12eSEd Maste -e ENC | --encoding=ENC Select the character encoding to use.\n\ 450a85fe12eSEd Maste -f | --print-file-name Print the file name before each string.\n\ 451a85fe12eSEd Maste -h | --help Print a help message and exit.\n\ 452a85fe12eSEd Maste -n N | --bytes=N | -N Print sequences with 'N' or more characters.\n\ 453a85fe12eSEd Maste -o Print offsets in octal.\n\ 454a85fe12eSEd Maste -t R | --radix=R Print offsets using the radix named by 'R'.\n\ 455a85fe12eSEd Maste -v | --version Print a version identifier and exit.\n" 456a85fe12eSEd Maste 457a85fe12eSEd Maste void 458a85fe12eSEd Maste usage(void) 459a85fe12eSEd Maste { 4604f486ad6SMariusz Zaborski 4614f486ad6SMariusz Zaborski fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); 462a85fe12eSEd Maste exit(EXIT_FAILURE); 463a85fe12eSEd Maste } 464a85fe12eSEd Maste 465a85fe12eSEd Maste void 466a85fe12eSEd Maste show_version(void) 467a85fe12eSEd Maste { 4684f486ad6SMariusz Zaborski 4694f486ad6SMariusz Zaborski printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); 470a85fe12eSEd Maste exit(EXIT_SUCCESS); 471a85fe12eSEd Maste } 472