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> 284f486ad6SMariusz Zaborski #include <sys/stat.h> 29a85fe12eSEd Maste 30a85fe12eSEd Maste #include <ctype.h> 31a85fe12eSEd Maste #include <err.h> 32a85fe12eSEd Maste #include <errno.h> 33a85fe12eSEd Maste #include <fcntl.h> 34a85fe12eSEd Maste #include <getopt.h> 35a85fe12eSEd Maste #include <inttypes.h> 36a85fe12eSEd Maste #include <stdint.h> 37a85fe12eSEd Maste #include <stdio.h> 38a85fe12eSEd Maste #include <stdlib.h> 39a85fe12eSEd Maste #include <string.h> 40839529caSEd Maste #include <sysexits.h> 41a85fe12eSEd Maste #include <unistd.h> 42a85fe12eSEd Maste 43a85fe12eSEd Maste #include <libelf.h> 44a85fe12eSEd Maste #include <libelftc.h> 45a85fe12eSEd Maste #include <gelf.h> 46a85fe12eSEd Maste 47a85fe12eSEd Maste #include "_elftc.h" 48a85fe12eSEd Maste 49*ae500c1fSEd Maste ELFTC_VCSID("$Id: strings.c 3648 2018-11-22 23:26:43Z emaste $"); 50a85fe12eSEd Maste 51a85fe12eSEd Maste enum radix_style { 52a85fe12eSEd Maste RADIX_DECIMAL, 53a85fe12eSEd Maste RADIX_HEX, 54a85fe12eSEd Maste RADIX_OCTAL 55a85fe12eSEd Maste }; 56a85fe12eSEd Maste 57a85fe12eSEd Maste enum encoding_style { 58a85fe12eSEd Maste ENCODING_7BIT, 59a85fe12eSEd Maste ENCODING_8BIT, 60a85fe12eSEd Maste ENCODING_16BIT_BIG, 61a85fe12eSEd Maste ENCODING_16BIT_LITTLE, 62a85fe12eSEd Maste ENCODING_32BIT_BIG, 63a85fe12eSEd Maste ENCODING_32BIT_LITTLE 64a85fe12eSEd Maste }; 65a85fe12eSEd Maste 66a85fe12eSEd Maste #define PRINTABLE(c) \ 67a85fe12eSEd Maste ((c) >= 0 && (c) <= 255 && \ 68a85fe12eSEd Maste ((c) == '\t' || isprint((c)) || \ 69a85fe12eSEd Maste (encoding == ENCODING_8BIT && (c) > 127))) 70a85fe12eSEd Maste 71839529caSEd Maste static int encoding_size, entire_file, show_filename, show_loc; 7250f69bfbSEd Maste static enum encoding_style encoding; 7350f69bfbSEd Maste static enum radix_style radix; 74839529caSEd Maste static intmax_t min_len; 75a85fe12eSEd Maste 76a85fe12eSEd Maste static struct option strings_longopts[] = { 77a85fe12eSEd Maste { "all", no_argument, NULL, 'a'}, 78a85fe12eSEd Maste { "bytes", required_argument, NULL, 'n'}, 79a85fe12eSEd Maste { "encoding", required_argument, NULL, 'e'}, 80a85fe12eSEd Maste { "help", no_argument, NULL, 'h'}, 81a85fe12eSEd Maste { "print-file-name", no_argument, NULL, 'f'}, 82a85fe12eSEd Maste { "radix", required_argument, NULL, 't'}, 83a85fe12eSEd Maste { "version", no_argument, NULL, 'v'}, 84a85fe12eSEd Maste { NULL, 0, NULL, 0 } 85a85fe12eSEd Maste }; 86a85fe12eSEd Maste 87a85fe12eSEd Maste long getcharacter(void); 88a85fe12eSEd Maste int handle_file(const char *); 89a85fe12eSEd Maste int handle_elf(const char *, int); 90a85fe12eSEd Maste int handle_binary(const char *, int); 91a85fe12eSEd Maste int find_strings(const char *, off_t, off_t); 92a85fe12eSEd Maste void show_version(void); 93a85fe12eSEd Maste void usage(void); 94a85fe12eSEd Maste 95a85fe12eSEd Maste /* 96a85fe12eSEd Maste * strings(1) extracts text(contiguous printable characters) 97a85fe12eSEd Maste * from elf and binary files. 98a85fe12eSEd Maste */ 99a85fe12eSEd Maste int 100a85fe12eSEd Maste main(int argc, char **argv) 101a85fe12eSEd Maste { 102a85fe12eSEd Maste int ch, rc; 103a85fe12eSEd Maste 104f8d647b4SEd Maste rc = 0; 105a85fe12eSEd Maste min_len = 0; 106a85fe12eSEd Maste encoding_size = 1; 107a85fe12eSEd Maste if (elf_version(EV_CURRENT) == EV_NONE) 108a85fe12eSEd Maste errx(EXIT_FAILURE, "ELF library initialization failed: %s", 109a85fe12eSEd Maste elf_errmsg(-1)); 110a85fe12eSEd Maste 111a85fe12eSEd Maste while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", 1124f486ad6SMariusz Zaborski strings_longopts, NULL)) != -1) { 113a85fe12eSEd Maste switch ((char)ch) { 114a85fe12eSEd Maste case 'a': 115a85fe12eSEd Maste entire_file = 1; 116a85fe12eSEd Maste break; 117a85fe12eSEd Maste case 'e': 118a85fe12eSEd Maste if (*optarg == 's') { 119a85fe12eSEd Maste encoding = ENCODING_7BIT; 120a85fe12eSEd Maste } else if (*optarg == 'S') { 121a85fe12eSEd Maste encoding = ENCODING_8BIT; 122a85fe12eSEd Maste } else if (*optarg == 'b') { 123a85fe12eSEd Maste encoding = ENCODING_16BIT_BIG; 124a85fe12eSEd Maste encoding_size = 2; 125a85fe12eSEd Maste } else if (*optarg == 'B') { 126a85fe12eSEd Maste encoding = ENCODING_32BIT_BIG; 127a85fe12eSEd Maste encoding_size = 4; 128a85fe12eSEd Maste } else if (*optarg == 'l') { 129a85fe12eSEd Maste encoding = ENCODING_16BIT_LITTLE; 130a85fe12eSEd Maste encoding_size = 2; 131a85fe12eSEd Maste } else if (*optarg == 'L') { 132a85fe12eSEd Maste encoding = ENCODING_32BIT_LITTLE; 133a85fe12eSEd Maste encoding_size = 4; 134a85fe12eSEd Maste } else 135a85fe12eSEd Maste usage(); 136a85fe12eSEd Maste /* NOTREACHED */ 137a85fe12eSEd Maste break; 138a85fe12eSEd Maste case 'f': 139a85fe12eSEd Maste show_filename = 1; 140a85fe12eSEd Maste break; 141a85fe12eSEd Maste case 'n': 142839529caSEd Maste min_len = strtoimax(optarg, (char**)NULL, 10); 143839529caSEd Maste if (min_len <= 0) 144839529caSEd Maste errx(EX_USAGE, "option -n should specify a " 145839529caSEd Maste "positive decimal integer."); 146a85fe12eSEd Maste break; 147a85fe12eSEd Maste case 'o': 148a85fe12eSEd Maste show_loc = 1; 149a85fe12eSEd Maste radix = RADIX_OCTAL; 150a85fe12eSEd Maste break; 151a85fe12eSEd Maste case 't': 152a85fe12eSEd Maste show_loc = 1; 153a85fe12eSEd Maste if (*optarg == 'd') 154a85fe12eSEd Maste radix = RADIX_DECIMAL; 155a85fe12eSEd Maste else if (*optarg == 'o') 156a85fe12eSEd Maste radix = RADIX_OCTAL; 157a85fe12eSEd Maste else if (*optarg == 'x') 158a85fe12eSEd Maste radix = RADIX_HEX; 159a85fe12eSEd Maste else 160a85fe12eSEd Maste usage(); 161a85fe12eSEd Maste /* NOTREACHED */ 162a85fe12eSEd Maste break; 163a85fe12eSEd Maste case 'v': 164a85fe12eSEd Maste case 'V': 165a85fe12eSEd Maste show_version(); 166a85fe12eSEd Maste /* NOTREACHED */ 167a85fe12eSEd Maste case '0': 168a85fe12eSEd Maste case '1': 169a85fe12eSEd Maste case '2': 170a85fe12eSEd Maste case '3': 171a85fe12eSEd Maste case '4': 172a85fe12eSEd Maste case '5': 173a85fe12eSEd Maste case '6': 174a85fe12eSEd Maste case '7': 175a85fe12eSEd Maste case '8': 176a85fe12eSEd Maste case '9': 177a85fe12eSEd Maste min_len *= 10; 178a85fe12eSEd Maste min_len += ch - '0'; 179a85fe12eSEd Maste break; 180a85fe12eSEd Maste case 'h': 181a85fe12eSEd Maste case '?': 182a85fe12eSEd Maste default: 183a85fe12eSEd Maste usage(); 184a85fe12eSEd Maste /* NOTREACHED */ 185a85fe12eSEd Maste } 1864f486ad6SMariusz Zaborski } 187a85fe12eSEd Maste argc -= optind; 188a85fe12eSEd Maste argv += optind; 189a85fe12eSEd Maste 1904f486ad6SMariusz Zaborski if (min_len == 0) 191a85fe12eSEd Maste min_len = 4; 1924f486ad6SMariusz Zaborski if (*argv == NULL) 1937ee12615SEd Maste rc = find_strings("{standard input}", 0, 0); 1944f486ad6SMariusz Zaborski else while (*argv != NULL) { 195f8d647b4SEd Maste if (handle_file(*argv) != 0) 196f8d647b4SEd Maste rc = 1; 197a85fe12eSEd Maste argv++; 198a85fe12eSEd Maste } 199a85fe12eSEd Maste return (rc); 200a85fe12eSEd Maste } 201a85fe12eSEd Maste 202a85fe12eSEd Maste int 203a85fe12eSEd Maste handle_file(const char *name) 204a85fe12eSEd Maste { 205a85fe12eSEd Maste int fd, rt; 206a85fe12eSEd Maste 207a85fe12eSEd Maste if (name == NULL) 208f8d647b4SEd Maste return (1); 209a85fe12eSEd Maste if (freopen(name, "rb", stdin) == NULL) { 210a85fe12eSEd Maste warnx("'%s': %s", name, strerror(errno)); 211f8d647b4SEd Maste return (1); 212a85fe12eSEd Maste } 213a85fe12eSEd Maste 214a85fe12eSEd Maste fd = fileno(stdin); 215a85fe12eSEd Maste if (fd < 0) 216f8d647b4SEd Maste return (1); 217a85fe12eSEd Maste rt = handle_elf(name, fd); 218a85fe12eSEd Maste return (rt); 219a85fe12eSEd Maste } 220a85fe12eSEd Maste 221a85fe12eSEd Maste /* 222a85fe12eSEd Maste * Files not understood by handle_elf, will be passed off here and will 223a85fe12eSEd Maste * treated as a binary file. This would include text file, core dumps ... 224a85fe12eSEd Maste */ 225a85fe12eSEd Maste int 226a85fe12eSEd Maste handle_binary(const char *name, int fd) 227a85fe12eSEd Maste { 228a85fe12eSEd Maste struct stat buf; 229a85fe12eSEd Maste 2304f486ad6SMariusz Zaborski memset(&buf, 0, sizeof(buf)); 2314f486ad6SMariusz Zaborski (void)lseek(fd, 0, SEEK_SET); 232a85fe12eSEd Maste if (!fstat(fd, &buf)) 2334f486ad6SMariusz Zaborski return (find_strings(name, 0, buf.st_size)); 234f8d647b4SEd Maste return (1); 235a85fe12eSEd Maste } 236a85fe12eSEd Maste 237a85fe12eSEd Maste /* 238a85fe12eSEd Maste * Will analyse a file to see if it ELF, other files including ar(1), 239a85fe12eSEd Maste * core dumps are passed off and treated as flat binary files. Unlike 240a85fe12eSEd Maste * GNU size in FreeBSD this routine will not treat ELF object from 241a85fe12eSEd Maste * different archs as flat binary files(has to overridden using -a). 242a85fe12eSEd Maste */ 243a85fe12eSEd Maste int 244a85fe12eSEd Maste handle_elf(const char *name, int fd) 245a85fe12eSEd Maste { 246a85fe12eSEd Maste GElf_Ehdr elfhdr; 247a85fe12eSEd Maste GElf_Shdr shdr; 248a85fe12eSEd Maste Elf *elf; 249a85fe12eSEd Maste Elf_Scn *scn; 250a85fe12eSEd Maste int rc; 251a85fe12eSEd Maste 252f8d647b4SEd Maste rc = 0; 253b6b6f9ccSEd Maste /* If entire file is chosen, treat it as a binary file */ 254a85fe12eSEd Maste if (entire_file) 255a85fe12eSEd Maste return (handle_binary(name, fd)); 256a85fe12eSEd Maste 2574f486ad6SMariusz Zaborski (void)lseek(fd, 0, SEEK_SET); 258a85fe12eSEd Maste elf = elf_begin(fd, ELF_C_READ, NULL); 259a85fe12eSEd Maste if (elf_kind(elf) != ELF_K_ELF) { 260a85fe12eSEd Maste (void)elf_end(elf); 261a85fe12eSEd Maste return (handle_binary(name, fd)); 262a85fe12eSEd Maste } 263a85fe12eSEd Maste 264a85fe12eSEd Maste if (gelf_getehdr(elf, &elfhdr) == NULL) { 265a85fe12eSEd Maste (void)elf_end(elf); 266a85fe12eSEd Maste warnx("%s: ELF file could not be processed", name); 267f8d647b4SEd Maste return (1); 268a85fe12eSEd Maste } 269a85fe12eSEd Maste 270a85fe12eSEd Maste if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { 271a85fe12eSEd Maste (void)elf_end(elf); 272a85fe12eSEd Maste return (handle_binary(name, fd)); 273a85fe12eSEd Maste } else { 274a85fe12eSEd Maste scn = NULL; 275a85fe12eSEd Maste while ((scn = elf_nextscn(elf, scn)) != NULL) { 276a85fe12eSEd Maste if (gelf_getshdr(scn, &shdr) == NULL) 277a85fe12eSEd Maste continue; 278a85fe12eSEd Maste if (shdr.sh_type != SHT_NOBITS && 279a85fe12eSEd Maste (shdr.sh_flags & SHF_ALLOC) != 0) { 280a85fe12eSEd Maste rc = find_strings(name, shdr.sh_offset, 281a85fe12eSEd Maste shdr.sh_size); 282a85fe12eSEd Maste } 283a85fe12eSEd Maste } 284a85fe12eSEd Maste } 285a85fe12eSEd Maste (void)elf_end(elf); 286a85fe12eSEd Maste return (rc); 287a85fe12eSEd Maste } 288a85fe12eSEd Maste 289a85fe12eSEd Maste /* 290a85fe12eSEd Maste * Retrieves a character from input stream based on the encoding 291a85fe12eSEd Maste * type requested. 292a85fe12eSEd Maste */ 293a85fe12eSEd Maste long 294a85fe12eSEd Maste getcharacter(void) 295a85fe12eSEd Maste { 296a85fe12eSEd Maste long rt; 297a85fe12eSEd Maste int i; 298a85fe12eSEd Maste char buf[4], c; 299a85fe12eSEd Maste 300a85fe12eSEd Maste rt = EOF; 301a85fe12eSEd Maste for(i = 0; i < encoding_size; i++) { 302a85fe12eSEd Maste c = getc(stdin); 303a85fe12eSEd Maste if (feof(stdin)) 304a85fe12eSEd Maste return (EOF); 305a85fe12eSEd Maste buf[i] = c; 306a85fe12eSEd Maste } 307a85fe12eSEd Maste 308a85fe12eSEd Maste switch (encoding) { 309a85fe12eSEd Maste case ENCODING_7BIT: 310a85fe12eSEd Maste case ENCODING_8BIT: 311a85fe12eSEd Maste rt = buf[0]; 312a85fe12eSEd Maste break; 313a85fe12eSEd Maste case ENCODING_16BIT_BIG: 314a85fe12eSEd Maste rt = (buf[0] << 8) | buf[1]; 315a85fe12eSEd Maste break; 316a85fe12eSEd Maste case ENCODING_16BIT_LITTLE: 317a85fe12eSEd Maste rt = buf[0] | (buf[1] << 8); 318a85fe12eSEd Maste break; 319a85fe12eSEd Maste case ENCODING_32BIT_BIG: 320a85fe12eSEd Maste rt = ((long) buf[0] << 24) | ((long) buf[1] << 16) | 321a85fe12eSEd Maste ((long) buf[2] << 8) | buf[3]; 322a85fe12eSEd Maste break; 323a85fe12eSEd Maste case ENCODING_32BIT_LITTLE: 324a85fe12eSEd Maste rt = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | 325a85fe12eSEd Maste ((long) buf[3] << 24); 326a85fe12eSEd Maste break; 327a85fe12eSEd Maste } 328a85fe12eSEd Maste return (rt); 329a85fe12eSEd Maste } 330a85fe12eSEd Maste 331a85fe12eSEd Maste /* 332a85fe12eSEd Maste * Input stream stdin is read until the end of file is reached or until 333a85fe12eSEd Maste * the section size is reached in case of ELF files. Contiguous 334a85fe12eSEd Maste * characters of >= min_size(default 4) will be displayed. 335a85fe12eSEd Maste */ 336a85fe12eSEd Maste int 337a85fe12eSEd Maste find_strings(const char *name, off_t offset, off_t size) 338a85fe12eSEd Maste { 339a85fe12eSEd Maste off_t cur_off, start_off; 340a85fe12eSEd Maste char *obuf; 341a85fe12eSEd Maste long c; 342a85fe12eSEd Maste int i; 343a85fe12eSEd Maste 344a85fe12eSEd Maste if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { 3454f486ad6SMariusz Zaborski fprintf(stderr, "Unable to allocate memory: %s\n", 346a85fe12eSEd Maste strerror(errno)); 347f8d647b4SEd Maste return (1); 348a85fe12eSEd Maste } 349a85fe12eSEd Maste 350a85fe12eSEd Maste (void)fseeko(stdin, offset, SEEK_SET); 351a85fe12eSEd Maste cur_off = offset; 352a85fe12eSEd Maste start_off = 0; 353248b5d08SMateusz Guzik for (;;) { 354a85fe12eSEd Maste if ((offset + size) && (cur_off >= offset + size)) 355a85fe12eSEd Maste break; 356a85fe12eSEd Maste start_off = cur_off; 357a85fe12eSEd Maste memset(obuf, 0, min_len + 1); 358a85fe12eSEd Maste for(i = 0; i < min_len; i++) { 359a85fe12eSEd Maste c = getcharacter(); 360a85fe12eSEd Maste if (c == EOF && feof(stdin)) 361a85fe12eSEd Maste goto _exit1; 362a85fe12eSEd Maste if (PRINTABLE(c)) { 363a85fe12eSEd Maste obuf[i] = c; 364a85fe12eSEd Maste obuf[i + 1] = 0; 365a85fe12eSEd Maste cur_off += encoding_size; 366a85fe12eSEd Maste } else { 367a85fe12eSEd Maste if (encoding == ENCODING_8BIT && 368a85fe12eSEd Maste (uint8_t)c > 127) { 369a85fe12eSEd Maste obuf[i] = c; 370a85fe12eSEd Maste obuf[i + 1] = 0; 371a85fe12eSEd Maste cur_off += encoding_size; 372a85fe12eSEd Maste continue; 373a85fe12eSEd Maste } 374a85fe12eSEd Maste cur_off += encoding_size; 375a85fe12eSEd Maste break; 376a85fe12eSEd Maste } 377a85fe12eSEd Maste } 378a85fe12eSEd Maste 379a85fe12eSEd Maste if (i >= min_len && ((cur_off <= offset + size) || 380a85fe12eSEd Maste !(offset + size))) { 381a85fe12eSEd Maste if (show_filename) 382a85fe12eSEd Maste printf("%s: ", name); 383a85fe12eSEd Maste if (show_loc) { 384a85fe12eSEd Maste switch (radix) { 385a85fe12eSEd Maste case RADIX_DECIMAL: 3864f486ad6SMariusz Zaborski printf("%7ju ", (uintmax_t)start_off); 387a85fe12eSEd Maste break; 388a85fe12eSEd Maste case RADIX_HEX: 3894f486ad6SMariusz Zaborski printf("%7jx ", (uintmax_t)start_off); 390a85fe12eSEd Maste break; 391a85fe12eSEd Maste case RADIX_OCTAL: 3924f486ad6SMariusz Zaborski printf("%7jo ", (uintmax_t)start_off); 393a85fe12eSEd Maste break; 394a85fe12eSEd Maste } 395a85fe12eSEd Maste } 396a85fe12eSEd Maste printf("%s", obuf); 397a85fe12eSEd Maste 398248b5d08SMateusz Guzik for (;;) { 399a85fe12eSEd Maste if ((offset + size) && 400a85fe12eSEd Maste (cur_off >= offset + size)) 401a85fe12eSEd Maste break; 402a85fe12eSEd Maste c = getcharacter(); 403a85fe12eSEd Maste cur_off += encoding_size; 404a85fe12eSEd Maste if (encoding == ENCODING_8BIT && 405a85fe12eSEd Maste (uint8_t)c > 127) { 406a85fe12eSEd Maste putchar(c); 407a85fe12eSEd Maste continue; 408a85fe12eSEd Maste } 409a85fe12eSEd Maste if (!PRINTABLE(c) || c == EOF) 410a85fe12eSEd Maste break; 411a85fe12eSEd Maste putchar(c); 412a85fe12eSEd Maste } 413a85fe12eSEd Maste putchar('\n'); 414a85fe12eSEd Maste } 415a85fe12eSEd Maste } 416a85fe12eSEd Maste _exit1: 417a85fe12eSEd Maste free(obuf); 418f8d647b4SEd Maste return (0); 419a85fe12eSEd Maste } 420a85fe12eSEd Maste 421a85fe12eSEd Maste #define USAGE_MESSAGE "\ 422a85fe12eSEd Maste Usage: %s [options] [file...]\n\ 423a85fe12eSEd Maste Print contiguous sequences of printable characters.\n\n\ 424a85fe12eSEd Maste Options:\n\ 425a85fe12eSEd Maste -a | --all Scan the entire file for strings.\n\ 426a85fe12eSEd Maste -e ENC | --encoding=ENC Select the character encoding to use.\n\ 427a85fe12eSEd Maste -f | --print-file-name Print the file name before each string.\n\ 428a85fe12eSEd Maste -h | --help Print a help message and exit.\n\ 429a85fe12eSEd Maste -n N | --bytes=N | -N Print sequences with 'N' or more characters.\n\ 430a85fe12eSEd Maste -o Print offsets in octal.\n\ 431a85fe12eSEd Maste -t R | --radix=R Print offsets using the radix named by 'R'.\n\ 432a85fe12eSEd Maste -v | --version Print a version identifier and exit.\n" 433a85fe12eSEd Maste 434a85fe12eSEd Maste void 435a85fe12eSEd Maste usage(void) 436a85fe12eSEd Maste { 4374f486ad6SMariusz Zaborski 4384f486ad6SMariusz Zaborski fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); 439a85fe12eSEd Maste exit(EXIT_FAILURE); 440a85fe12eSEd Maste } 441a85fe12eSEd Maste 442a85fe12eSEd Maste void 443a85fe12eSEd Maste show_version(void) 444a85fe12eSEd Maste { 4454f486ad6SMariusz Zaborski 4464f486ad6SMariusz Zaborski printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); 447a85fe12eSEd Maste exit(EXIT_SUCCESS); 448a85fe12eSEd Maste } 449