wheels@mks.UUCP (Gerry Wheeler) (02/07/89)
I haven't seen a version of strings for MINIX, so here is my attempt.
It doesn't have some of the options of other versions I have seen, but
it is quite functional as is. If someone has need of other options,
perhaps they could post their changes, or email me with a request and
I'll consider adding it.
I've also compiled this on U**x and MS-DOS. The only change required
for DOS was that the fopen() had to have binary mode added, so it looked
like this:
fopen(argv[arg], "rb")
This prevents DOS from returning EOF when it reads a ^Z character.
------------------------------ cut here ------------------------------
/*
* This is a simple version of the strings command to find and
* display sequences of printable characters in a file. This
* version does not have any knowledge about the format of any
* file, so it searches the entire file.
*
* Written by Gerry Wheeler, February 5, 1989. Permission is
* granted to use this source code for non-profit purposes,
* provided this and any other acknowledgements are included.
*
* When compiled on MINIX ST, I found that a stack size of 5000
* bytes was adequate. For example:
*
* cc -O -o strings strings.c
* chmem =5000 strings
*/
#include <stdio.h>
#define DEF_LENGTH 5 /* default minimum string length */
#define MAX_LENGTH 100 /* maximum minimum string length */
#define isprintable(x) (((x)>=' ')&&((x)<='~'))
static char* Ack = "strings, version 1.0, by Gerry Wheeler, 89/2/5";
/*
* Find and print the strings in a file.
*/
static void strings(fp, min_length, name)
FILE *fp;
int min_length;
char *name;
{
static char buf[MAX_LENGTH];
int c, count;
/*
* Look for a sequence of min_length printable characters.
* If found, print them, and then print any following printable
* characters.
*/
count = 0;
while ((c = getc(fp)) != EOF) {
/*
* If we find a printable character, add it to the
* buffer. Otherwise, reset the count to zero and
* look some more.
*/
if (isprintable((char)c))
buf[count++] = (char)c;
else
count = 0;
if (count >= min_length) {
/*
* If we have the minimum number of printable
* characters, print the file name, and the
* characters.
*/
if (*name != '\0')
printf("%s: ", name);
for (count = 0; count < min_length; ++count)
putchar(buf[count]);
/*
* Then print any following printable characters.
*/
while ((c = getc(fp)) != EOF) {
if (isprintable((char)c))
putchar((char)c);
else
break;
}
/*
* Print a newline to separate sets of output.
*/
putchar('\n');
count = 0; /* reset counter for next time */
}
}
fflush(stdout); /* flush one file's output before starting another */
}
main(argc, argv)
int argc;
char *argv[];
{
int min_length = DEF_LENGTH; /* minimum string length */
int arg = 1; /* command arg being examined */
/*
* See if the first argument is a string length.
*/
if (argc > 1 && argv[1][0] == '-') {
/*
* If the hyphen is followed by a non-digit, assume they
* are unaware of the correct options, and give a usage
* message.
*/
if (argv[1][1] < '0' || argv[1][1] > '9') {
fprintf(stderr, "usage: %s [-minsize] [file ...]\n", argv[0]);
exit(1);
}
min_length = atoi(&argv[1][1]);
if (min_length < 1 || min_length > MAX_LENGTH) {
fprintf(stderr, "%s: string length must be between 1 and %d\n", argv[0], MAX_LENGTH);
exit(1);
}
arg = 2;
}
/*
* If there are no more arguments, we have to use the standard
* input for data. Otherwise, use each of the arguments as a
* file name and try to open it.
*/
if (arg >= argc)
strings(stdin, min_length, "");
else {
int shownames;
/*
* If there is more than one file to show, remember
* that we have to show the file names.
*/
shownames = argc > (arg + 1);
while (arg < argc) {
FILE *fp;
if ((fp = fopen(argv[arg], "r")) != NULL) {
strings(fp, min_length, shownames ? argv[arg] : "");
fclose(fp);
}
else {
fprintf(stderr, "%s: can't open file \"%s\"\n", argv[0], argv[arg]);
exit(1);
}
++arg;
}
}
}
--
Gerry Wheeler Phone: (519)884-2251
Mortice Kern Systems Inc. UUCP: uunet!watmath!mks!wheels
35 King St. North BIX: join mks
Waterloo, Ontario N2J 2W9 CompuServe: 73260,1043