5 kx /*
5 kx * Copyright (c) 1980, 1987 The Regents of the University of California.
5 kx * All rights reserved.
5 kx *
5 kx * Redistribution and use in source and binary forms, with or without
5 kx * modification, are permitted provided that the following conditions
5 kx * are met:
5 kx * 1. Redistributions of source code must retain the above copyright
5 kx * notice, this list of conditions and the following disclaimer.
5 kx * 2. Redistributions in binary form must reproduce the above copyright
5 kx * notice, this list of conditions and the following disclaimer in the
5 kx * documentation and/or other materials provided with the distribution.
5 kx * 3. All advertising materials mentioning features or use of this software
5 kx * must display the following acknowledgement:
5 kx * This product includes software developed by the University of
5 kx * California, Berkeley and its contributors.
5 kx * 4. Neither the name of the University nor the names of its contributors
5 kx * may be used to endorse or promote products derived from this software
5 kx * without specific prior written permission.
5 kx *
5 kx * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
5 kx * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5 kx * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5 kx * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
5 kx * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5 kx * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5 kx * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5 kx * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5 kx * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5 kx * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5 kx * SUCH DAMAGE.
5 kx *
5 kx * Wed Jun 22 22:22:37 1994, faith@cs.unc.edu:
5 kx * Added internationalization patches from Vitor Duarte <vad@fct.unl.pt>
5 kx */
5 kx
5 kx #include <sys/types.h>
5 kx #include <fcntl.h>
5 kx #include <errno.h>
5 kx #include <a.out.h>
5 kx #include <unistd.h>
5 kx #include <stdio.h>
5 kx #include <ctype.h>
5 kx #include <stdlib.h>
5 kx #include <string.h>
5 kx #include <locale.h>
5 kx
5 kx #define DEF_LEN 4 /* default minimum string length */
5 kx #if 0
5 kx #define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t'))
5 kx #else
5 kx #define ISSTR(ch) (isprint(ch) || ch == '\t')
5 kx #endif
5 kx
5 kx typedef struct exec EXEC; /* struct exec cast */
5 kx
5 kx static long foff; /* offset in the file */
5 kx static int hcnt, /* head count */
5 kx head_len, /* length of header */
5 kx read_len; /* length to read */
5 kx static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */
5 kx
5 kx static int getch();
5 kx static void usage();
5 kx
5 kx int main(argc, argv)
5 kx int argc;
5 kx char **argv;
5 kx {
5 kx extern char *optarg;
5 kx extern int optind;
5 kx register int ch, cnt;
5 kx register u_char *C;
5 kx EXEC *head;
5 kx int exitcode, minlen;
5 kx short asdata, oflg, fflg;
5 kx u_char *bfr;
5 kx char *file, *p;
5 kx
5 kx setlocale(LC_CTYPE, "");
5 kx
5 kx
5 kx /*
5 kx * for backward compatibility, allow '-' to specify 'a' flag; no
5 kx * longer documented in the man page or usage string.
5 kx */
5 kx asdata = exitcode = fflg = oflg = 0;
5 kx minlen = -1;
5 kx while ((ch = getopt(argc, argv, "-0123456789an:of")) != EOF)
5 kx switch((char)ch) {
5 kx case '0': case '1': case '2': case '3': case '4':
5 kx case '5': case '6': case '7': case '8': case '9':
5 kx /*
5 kx * kludge: strings was originally designed to take
5 kx * a number after a dash.
5 kx */
5 kx if (minlen == -1) {
5 kx p = argv[optind - 1];
5 kx if (p[0] == '-' && p[1] == ch && !p[2])
5 kx minlen = atoi(++p);
5 kx else
5 kx minlen = atoi(argv[optind] + 1);
5 kx }
5 kx break;
5 kx case '-':
5 kx case 'a':
5 kx asdata = 1;
5 kx break;
5 kx case 'f':
5 kx fflg = 1;
5 kx break;
5 kx case 'n':
5 kx minlen = atoi(optarg);
5 kx break;
5 kx case 'o':
5 kx oflg = 1;
5 kx break;
5 kx case '?':
5 kx default:
5 kx usage();
5 kx }
5 kx argc -= optind;
5 kx argv += optind;
5 kx
5 kx if (minlen == -1)
5 kx minlen = DEF_LEN;
5 kx
5 kx if (!(bfr = malloc((u_int)minlen + 1))) {
5 kx (void)fprintf(stderr, "strings: %s\n", strerror(errno));
5 kx exit(1);
5 kx }
5 kx bfr[minlen] = '\0';
5 kx file = "stdin";
5 kx do {
5 kx if (*argv) {
5 kx file = *argv++;
5 kx if (!freopen(file, "r", stdin)) {
5 kx (void)fprintf(stderr,
5 kx "strings; %s: %s\n", file, strerror(errno));
5 kx exitcode = 1;
5 kx goto nextfile;
5 kx }
5 kx }
5 kx foff = 0;
5 kx #define DO_EVERYTHING() {read_len = -1; head_len = 0; goto start;}
5 kx read_len = -1;
5 kx if (asdata)
5 kx DO_EVERYTHING()
5 kx else {
5 kx head = (EXEC *)hbfr;
5 kx if ((head_len =
5 kx read(fileno(stdin), head, sizeof(EXEC))) == -1)
5 kx DO_EVERYTHING()
5 kx if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
5 kx foff = N_TXTOFF(*head);
5 kx if (fseek(stdin, foff, SEEK_SET) == -1)
5 kx DO_EVERYTHING()
5 kx read_len = head->a_text + head->a_data;
5 kx head_len = 0;
5 kx }
5 kx else
5 kx hcnt = 0;
5 kx }
5 kx start:
5 kx for (cnt = 0; (ch = getch()) != EOF;) {
5 kx if (ISSTR(ch)) {
5 kx if (!cnt)
5 kx C = bfr;
5 kx *C++ = ch;
5 kx if (++cnt < minlen)
5 kx continue;
5 kx if (fflg)
5 kx printf("%s:", file);
5 kx if (oflg)
5 kx printf("%07ld %s",
5 kx foff - minlen, (char *)bfr);
5 kx else
5 kx printf("%s", bfr);
5 kx while ((ch = getch()) != EOF && ISSTR(ch))
5 kx putchar((char)ch);
5 kx putchar('\n');
5 kx }
5 kx cnt = 0;
5 kx }
5 kx nextfile: ;
5 kx } while (*argv);
5 kx exit(exitcode);
5 kx }
5 kx
5 kx /*
5 kx * getch --
5 kx * get next character from wherever
5 kx */
5 kx static int
5 kx getch()
5 kx {
5 kx ++foff;
5 kx if (head_len) {
5 kx if (hcnt < head_len)
5 kx return((int)hbfr[hcnt++]);
5 kx head_len = 0;
5 kx }
5 kx if (read_len == -1 || read_len-- > 0)
5 kx return(getchar());
5 kx return(EOF);
5 kx }
5 kx
5 kx static void
5 kx usage()
5 kx {
5 kx (void)fprintf(stderr,
5 kx "usage: strings [-afo] [-n length] [file ... ]\n");
5 kx exit(1);
5 kx }