1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-19 10:53:58 +00:00

Use the vendor's 2.12.0_snap vendor version of this file as in rev 1.5.

This commit is contained in:
David E. O'Brien 2002-01-27 12:12:53 +00:00
parent eb18cc2ed5
commit 04f0ba0a6c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=89865

View File

@ -1,6 +1,6 @@
/* strings -- print the strings of printable characters in files
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
Free Software Foundation, Inc.
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -41,6 +41,11 @@
-o Like -to. (Some other implementations have -o like -to,
others like -td. We chose one arbitrarily.)
--encoding={s,b,l,B,L}
-e {s,b,l,B,L}
Select character encoding: single-byte, bigendian 16-bit,
littleendian 16-bit, bigendian 32-bit, littleendian 32-bit
--target=BFDNAME
Specify a non-default object file format.
@ -53,13 +58,16 @@
Written by Richard Stallman <rms@gnu.ai.mit.edu>
and David MacKenzie <djm@gnu.ai.mit.edu>. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "bfd.h"
#include <stdio.h>
#include <getopt.h>
#include <ctype.h>
#include <errno.h>
#include "bucomm.h"
#include "libiberty.h"
#include "safe-ctype.h"
/* Some platforms need to put stdin into binary mode, to read
binary files. */
@ -78,14 +86,7 @@
#endif
#endif
/* Not all printable characters have ASCII codes (depending upon the
LOCALE set) but on some older systems it is not safe to test isprint
without first testing isascii... */
#if defined isascii && !defined HAVE_LOCALE_H
#define isgraphic(c) (isascii (c) && (isprint (c) || (c) == '\t'))
#else
#define isgraphic(c) (isprint (c) || (c) == '\t')
#endif
#define isgraphic(c) (ISPRINT (c) || (c) == '\t')
#ifndef errno
extern int errno;
@ -94,6 +95,14 @@ extern int errno;
/* The BFD section flags that identify an initialized data section. */
#define DATA_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS)
#ifdef HAVE_FOPEN64
typedef off64_t file_off;
#define file_open(s,m) fopen64(s,m)
#else
typedef off_t file_off;
#define file_open(s,m) fopen(s,m)
#endif
/* Radix for printing addresses (must be 8, 10 or 16). */
static int address_radix;
@ -115,12 +124,17 @@ static boolean got_a_section;
/* The BFD object file format. */
static char *target;
/* The character encoding format. */
static char encoding;
static int encoding_bytes;
static struct option long_options[] =
{
{"all", no_argument, NULL, 'a'},
{"print-file-name", no_argument, NULL, 'f'},
{"bytes", required_argument, NULL, 'n'},
{"radix", required_argument, NULL, 't'},
{"encoding", required_argument, NULL, 'e'},
{"target", required_argument, NULL, 'T'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
@ -132,10 +146,14 @@ static boolean strings_object_file PARAMS ((const char *));
static boolean strings_file PARAMS ((char *file));
static int integer_arg PARAMS ((char *s));
static void print_strings PARAMS ((const char *filename, FILE *stream,
file_ptr address, int stop_point,
file_off address, int stop_point,
int magiccount, char *magic));
static void usage PARAMS ((FILE *stream, int status));
static long get_char PARAMS ((FILE *stream, file_off *address,
int *magiccount, char **magic));
int main PARAMS ((int, char **));
int
main (argc, argv)
int argc;
@ -145,7 +163,7 @@ main (argc, argv)
int exit_status = 0;
boolean files_given = false;
#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
#if defined (HAVE_SETLOCALE)
setlocale (LC_ALL, "");
#endif
bindtextdomain (PACKAGE, LOCALEDIR);
@ -158,8 +176,9 @@ main (argc, argv)
print_filenames = false;
datasection_only = true;
target = NULL;
encoding = 's';
while ((optc = getopt_long (argc, argv, "afn:ot:v0123456789",
while ((optc = getopt_long (argc, argv, "afhHn:ot:e:Vv0123456789",
long_options, (int *) 0)) != EOF)
{
switch (optc)
@ -172,6 +191,7 @@ main (argc, argv)
print_filenames = true;
break;
case 'H':
case 'h':
usage (stdout, 0);
@ -215,6 +235,13 @@ main (argc, argv)
target = optarg;
break;
case 'e':
if (optarg[1] != '\0')
usage (stderr, 1);
encoding = optarg[0];
break;
case 'V':
case 'v':
print_version ("strings");
break;
@ -234,6 +261,23 @@ main (argc, argv)
if (string_min < 0)
string_min = 4;
switch (encoding)
{
case 's':
encoding_bytes = 1;
break;
case 'b':
case 'l':
encoding_bytes = 2;
break;
case 'B':
case 'L':
encoding_bytes = 4;
break;
default:
usage (stderr, 1);
}
bfd_init ();
set_default_bfd_target ();
@ -344,10 +388,7 @@ strings_file (file)
{
FILE *stream;
stream = fopen (file, "rb");
/* Not all systems permit "rb", so try "r" if it failed. */
if (stream == NULL)
stream = fopen (file, "r");
stream = file_open (file, FOPEN_RB);
if (stream == NULL)
{
fprintf (stderr, "%s: ", program_name);
@ -355,7 +396,7 @@ strings_file (file)
return false;
}
print_strings (file, stream, (file_ptr) 0, 0, 0, (char *) 0);
print_strings (file, stream, (file_off) 0, 0, 0, (char *) 0);
if (fclose (stream) == EOF)
{
@ -368,6 +409,78 @@ strings_file (file)
return true;
}
/* Read the next character, return EOF if none available.
Assume that STREAM is positioned so that the next byte read
is at address ADDRESS in the file.
If STREAM is NULL, do not read from it.
The caller can supply a buffer of characters
to be processed before the data in STREAM.
MAGIC is the address of the buffer and
MAGICCOUNT is how many characters are in it. */
static long
get_char (stream, address, magiccount, magic)
FILE *stream;
file_off *address;
int *magiccount;
char **magic;
{
int c, i;
long r = EOF;
unsigned char buf[4];
for (i = 0; i < encoding_bytes; i++)
{
if (*magiccount)
{
(*magiccount)--;
c = *(*magic)++;
}
else
{
if (stream == NULL)
return EOF;
#ifdef HAVE_GETC_UNLOCKED
c = getc_unlocked (stream);
#else
c = getc (stream);
#endif
if (c == EOF)
return EOF;
}
(*address)++;
buf[i] = c;
}
switch (encoding)
{
case 's':
r = buf[0];
break;
case 'b':
r = (buf[0] << 8) | buf[1];
break;
case 'l':
r = buf[0] | (buf[1] << 8);
break;
case 'B':
r = ((long) buf[0] << 24) | ((long) buf[1] << 16) |
((long) buf[2] << 8) | buf[3];
break;
case 'L':
r = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) |
((long) buf[3] << 24);
break;
}
if (r == EOF)
return 0;
return r;
}
/* Find the strings in file FILENAME, read from STREAM.
Assume that STREAM is positioned so that the next byte read
is at address ADDRESS in the file.
@ -384,18 +497,18 @@ static void
print_strings (filename, stream, address, stop_point, magiccount, magic)
const char *filename;
FILE *stream;
file_ptr address;
file_off address;
int stop_point;
int magiccount;
char *magic;
{
char *buf = (char *) xmalloc (string_min + 1);
char *buf = (char *) xmalloc (sizeof (char) * (string_min + 1));
while (1)
{
file_ptr start;
file_off start;
int i;
int c;
long c;
/* See if the next `string_min' chars are all graphic chars. */
tryline:
@ -404,21 +517,10 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
start = address;
for (i = 0; i < string_min; i++)
{
if (magiccount)
{
magiccount--;
c = *magic++;
}
else
{
if (stream == NULL)
return;
c = getc (stream);
if (c == EOF)
return;
}
address++;
if (!isgraphic (c))
c = get_char (stream, &address, &magiccount, &magic);
if (c == EOF)
return;
if (c > 255 || c < 0 || !isgraphic (c))
/* Found a non-graphic. Try again starting with next char. */
goto tryline;
buf[i] = c;
@ -433,15 +535,48 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
switch (address_radix)
{
case 8:
printf ("%7lo ", (unsigned long) start);
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
if (sizeof (start) > sizeof (long))
printf ("%7Lo ", (unsigned long long) start);
else
#else
# if !BFD_HOST_64BIT_LONG
if (start != (unsigned long) start)
printf ("++%7lo ", (unsigned long) start);
else
# endif
#endif
printf ("%7lo ", (unsigned long) start);
break;
case 10:
printf ("%7ld ", (long) start);
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
if (sizeof (start) > sizeof (long))
printf ("%7Ld ", (unsigned long long) start);
else
#else
# if !BFD_HOST_64BIT_LONG
if (start != (unsigned long) start)
printf ("++%7ld ", (unsigned long) start);
else
# endif
#endif
printf ("%7ld ", (long) start);
break;
case 16:
printf ("%7lx ", (unsigned long) start);
#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2)
if (sizeof (start) > sizeof (long))
printf ("%7Lx ", (unsigned long long) start);
else
#else
# if !BFD_HOST_64BIT_LONG
if (start != (unsigned long) start)
printf ("%lx%8.8lx ", start >> 32, start & 0xffffffff);
else
# endif
#endif
printf ("%7lx ", (unsigned long) start);
break;
}
@ -450,21 +585,10 @@ print_strings (filename, stream, address, stop_point, magiccount, magic)
while (1)
{
if (magiccount)
{
magiccount--;
c = *magic++;
}
else
{
if (stream == NULL)
break;
c = getc (stream);
if (c == EOF)
break;
}
address++;
if (! isgraphic (c))
c = get_char (stream, &address, &magiccount, &magic);
if (c == EOF)
break;
if (c > 255 || c < 0 || !isgraphic (c))
break;
putchar (c);
}
@ -525,11 +649,20 @@ usage (stream, status)
FILE *stream;
int status;
{
fprintf (stream, _("\
Usage: %s [-afov] [-n min-len] [-min-len] [-t {o,x,d}] [-]\n\
[--all] [--print-file-name] [--bytes=min-len] [--radix={o,x,d}]\n\
[--target=bfdname] [--help] [--version] file...\n"),
program_name);
fprintf (stream, _("Usage: %s [option(s)] [file(s)]\n"), program_name);
fprintf (stream, _(" Display printable strings in [file(s)] (stdin by default)\n"));
fprintf (stream, _(" The options are:\n\
-a - --all Scan the entire file, not just the data section\n\
-f --print-file-name Print the name of the file before each string\n\
-n --bytes=[number] Locate & print any NUL-terminated sequence of at\n\
-<number> least [number] characters (default 4).\n\
-t --radix={o,x,d} Print the location of the string in base 8, 10 or 16\n\
-o An alias for --radix=o\n\
-T --target=<BFDNAME> Specify the binary file format\n\
-e --encoding={s,b,l,B,L} Select character size and endianness:\n\
s = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit\n\
-h --help Display this information\n\
-v --version Print the program's version number\n"));
list_supported_targets (program_name, stream);
if (status == 0)
fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);