121577Sdist /*
262257Sbostic * Copyright (c) 1980, 1987, 1993
362257Sbostic * The Regents of the University of California. All rights reserved.
435980Sbostic *
542691Sbostic * %sccs.include.redist.c%
621577Sdist */
721577Sdist
817267Ssam #ifndef lint
962257Sbostic static char copyright[] =
1062257Sbostic "@(#) Copyright (c) 1980, 1987, 1993\n\
1162257Sbostic The Regents of the University of California. All rights reserved.\n";
1235980Sbostic #endif /* not lint */
1317267Ssam
1421577Sdist #ifndef lint
15*65939Sbostic static char sccsid[] = "@(#)strings.c 8.2 (Berkeley) 01/28/94";
1635980Sbostic #endif /* not lint */
1721577Sdist
1830142Sbostic #include <sys/types.h>
19*65939Sbostic
20*65939Sbostic #include <a.out.h>
21*65939Sbostic #include <ctype.h>
22*65939Sbostic #include <errno.h>
2349503Sbostic #include <fcntl.h>
241105Sbill #include <stdio.h>
2549503Sbostic #include <stdlib.h>
2649503Sbostic #include <string.h>
27*65939Sbostic #include <unistd.h>
281105Sbill
2930142Sbostic #define DEF_LEN 4 /* default minimum string length */
3030142Sbostic #define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t'))
311105Sbill
3230142Sbostic typedef struct exec EXEC; /* struct exec cast */
331105Sbill
3430142Sbostic static long foff; /* offset in the file */
3530142Sbostic static int hcnt, /* head count */
3630142Sbostic head_len, /* length of header */
3730142Sbostic read_len; /* length to read */
3830142Sbostic static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */
391105Sbill
4049503Sbostic static void usage();
4149503Sbostic
main(argc,argv)4235980Sbostic main(argc, argv)
4335980Sbostic int argc;
4435980Sbostic char **argv;
451105Sbill {
4635980Sbostic extern char *optarg;
4735980Sbostic extern int optind;
4835980Sbostic register int ch, cnt;
4935980Sbostic register u_char *C;
5035980Sbostic EXEC *head;
5149503Sbostic int exitcode, minlen;
5247678Smarc short asdata, oflg, fflg;
5335980Sbostic u_char *bfr;
5449503Sbostic char *file, *p;
551105Sbill
5630142Sbostic /*
5730142Sbostic * for backward compatibility, allow '-' to specify 'a' flag; no
5830142Sbostic * longer documented in the man page or usage string.
5930142Sbostic */
6049503Sbostic asdata = exitcode = fflg = oflg = 0;
6135980Sbostic minlen = -1;
62*65939Sbostic while ((ch = getopt(argc, argv, "-0123456789an:of")) != EOF)
63*65939Sbostic switch (ch) {
6435980Sbostic case '0': case '1': case '2': case '3': case '4':
6535980Sbostic case '5': case '6': case '7': case '8': case '9':
6635980Sbostic /*
6735980Sbostic * kludge: strings was originally designed to take
6835980Sbostic * a number after a dash.
6935980Sbostic */
7035980Sbostic if (minlen == -1) {
7135980Sbostic p = argv[optind - 1];
7235980Sbostic if (p[0] == '-' && p[1] == ch && !p[2])
7335980Sbostic minlen = atoi(++p);
7435980Sbostic else
7535980Sbostic minlen = atoi(argv[optind] + 1);
761105Sbill }
7735980Sbostic break;
7835980Sbostic case '-':
7935980Sbostic case 'a':
8035980Sbostic asdata = 1;
8135980Sbostic break;
8249503Sbostic case 'f':
8349503Sbostic fflg = 1;
8449503Sbostic break;
8549503Sbostic case 'n':
8649503Sbostic minlen = atoi(optarg);
8749503Sbostic break;
8835980Sbostic case 'o':
8935980Sbostic oflg = 1;
9035980Sbostic break;
9135980Sbostic case '?':
9235980Sbostic default:
9349503Sbostic usage();
9435980Sbostic }
9535980Sbostic argc -= optind;
9635980Sbostic argv += optind;
9730142Sbostic
9835980Sbostic if (minlen == -1)
9935980Sbostic minlen = DEF_LEN;
100*65939Sbostic else {
101*65939Sbostic (void)fprintf(stderr, "strings: length less than 1\n");
102*65939Sbostic exit (1);
103*65939Sbostic }
10435980Sbostic
10549503Sbostic if (!(bfr = malloc((u_int)minlen))) {
10649503Sbostic (void)fprintf(stderr, "strings: %s\n", strerror(errno));
10735980Sbostic exit(1);
10830142Sbostic }
10935980Sbostic bfr[minlen] = '\0';
11049861Sbostic file = "stdin";
1111105Sbill do {
11230142Sbostic if (*argv) {
11347678Smarc file = *argv++;
11447678Smarc if (!freopen(file, "r", stdin)) {
11549503Sbostic (void)fprintf(stderr,
11650945Sbostic "strings: %s: %s\n", file, strerror(errno));
11747678Smarc exitcode = 1;
11847678Smarc goto nextfile;
1191105Sbill }
1201105Sbill }
12130142Sbostic foff = 0;
12247678Smarc #define DO_EVERYTHING() {read_len = -1; head_len = 0; goto start;}
12335980Sbostic read_len = -1;
12430142Sbostic if (asdata)
12547678Smarc DO_EVERYTHING()
12630142Sbostic else {
12730142Sbostic head = (EXEC *)hbfr;
12849503Sbostic if ((head_len =
12949503Sbostic read(fileno(stdin), head, sizeof(EXEC))) == -1)
13047678Smarc DO_EVERYTHING()
13130142Sbostic if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
13249497Sdonn foff = N_TXTOFF(*head);
13349503Sbostic if (fseek(stdin, foff, SEEK_SET) == -1)
13447678Smarc DO_EVERYTHING()
13549497Sdonn read_len = head->a_text + head->a_data;
13630142Sbostic head_len = 0;
13730142Sbostic }
13830142Sbostic else
13930142Sbostic hcnt = 0;
1401105Sbill }
14147678Smarc start:
14235980Sbostic for (cnt = 0; (ch = getch()) != EOF;) {
14330142Sbostic if (ISSTR(ch)) {
14430142Sbostic if (!cnt)
14530142Sbostic C = bfr;
14630142Sbostic *C++ = ch;
14730142Sbostic if (++cnt < minlen)
14830142Sbostic continue;
14947678Smarc if (fflg)
15047678Smarc printf("%s:", file);
1511105Sbill if (oflg)
15249503Sbostic printf("%07ld %s",
15349503Sbostic foff - minlen, (char *)bfr);
15430142Sbostic else
15549503Sbostic printf("%s", bfr);
15630142Sbostic while ((ch = getch()) != EOF && ISSTR(ch))
15730142Sbostic putchar((char)ch);
15830142Sbostic putchar('\n');
1591105Sbill }
16030142Sbostic cnt = 0;
1611105Sbill }
16247678Smarc nextfile: ;
16330142Sbostic } while (*argv);
16447678Smarc exit(exitcode);
1651105Sbill }
1661105Sbill
16730142Sbostic /*
16830142Sbostic * getch --
16930142Sbostic * get next character from wherever
17030142Sbostic */
getch()17130142Sbostic getch()
1721105Sbill {
17330142Sbostic ++foff;
17430142Sbostic if (head_len) {
17530142Sbostic if (hcnt < head_len)
17630142Sbostic return((int)hbfr[hcnt++]);
17730142Sbostic head_len = 0;
1781105Sbill }
17935980Sbostic if (read_len == -1 || read_len-- > 0)
18030142Sbostic return(getchar());
18130142Sbostic return(EOF);
1821105Sbill }
18349503Sbostic
18449503Sbostic static void
usage()18549503Sbostic usage()
18649503Sbostic {
18749503Sbostic (void)fprintf(stderr,
18849503Sbostic "usage: strings [-afo] [-n length] [file ... ]\n");
18949503Sbostic exit(1);
19049503Sbostic }
191