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