xref: /csrg-svn/usr.bin/strings/strings.c (revision 62257)
121577Sdist /*
2*62257Sbostic  * Copyright (c) 1980, 1987, 1993
3*62257Sbostic  *	The Regents of the University of California.  All rights reserved.
435980Sbostic  *
542691Sbostic  * %sccs.include.redist.c%
621577Sdist  */
721577Sdist 
817267Ssam #ifndef lint
9*62257Sbostic static char copyright[] =
10*62257Sbostic "@(#) Copyright (c) 1980, 1987, 1993\n\
11*62257Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1235980Sbostic #endif /* not lint */
1317267Ssam 
1421577Sdist #ifndef lint
15*62257Sbostic static char sccsid[] = "@(#)strings.c	8.1 (Berkeley) 06/06/93";
1635980Sbostic #endif /* not lint */
1721577Sdist 
1830142Sbostic #include <sys/types.h>
1949503Sbostic #include <fcntl.h>
2049503Sbostic #include <errno.h>
2130142Sbostic #include <a.out.h>
2249503Sbostic #include <unistd.h>
231105Sbill #include <stdio.h>
241105Sbill #include <ctype.h>
2549503Sbostic #include <stdlib.h>
2649503Sbostic #include <string.h>
271105Sbill 
2830142Sbostic #define DEF_LEN		4		/* default minimum string length */
2930142Sbostic #define ISSTR(ch)	(isascii(ch) && (isprint(ch) || ch == '\t'))
301105Sbill 
3130142Sbostic typedef struct exec	EXEC;		/* struct exec cast */
321105Sbill 
3330142Sbostic static long	foff;			/* offset in the file */
3430142Sbostic static int	hcnt,			/* head count */
3530142Sbostic 		head_len,		/* length of header */
3630142Sbostic 		read_len;		/* length to read */
3730142Sbostic static u_char	hbfr[sizeof(EXEC)];	/* buffer for struct exec */
381105Sbill 
3949503Sbostic static void usage();
4049503Sbostic 
4135980Sbostic main(argc, argv)
4235980Sbostic 	int argc;
4335980Sbostic 	char **argv;
441105Sbill {
4535980Sbostic 	extern char *optarg;
4635980Sbostic 	extern int optind;
4735980Sbostic 	register int ch, cnt;
4835980Sbostic 	register u_char *C;
4935980Sbostic 	EXEC *head;
5049503Sbostic 	int exitcode, minlen;
5147678Smarc 	short asdata, oflg, fflg;
5235980Sbostic 	u_char *bfr;
5349503Sbostic 	char *file, *p;
541105Sbill 
5530142Sbostic 	/*
5630142Sbostic 	 * for backward compatibility, allow '-' to specify 'a' flag; no
5730142Sbostic 	 * longer documented in the man page or usage string.
5830142Sbostic 	 */
5949503Sbostic 	asdata = exitcode = fflg = oflg = 0;
6035980Sbostic 	minlen = -1;
6149503Sbostic 	while ((ch = getopt(argc, argv, "-0123456789anof")) != EOF)
6235980Sbostic 		switch((char)ch) {
6335980Sbostic 		case '0': case '1': case '2': case '3': case '4':
6435980Sbostic 		case '5': case '6': case '7': case '8': case '9':
6535980Sbostic 			/*
6635980Sbostic 			 * kludge: strings was originally designed to take
6735980Sbostic 			 * a number after a dash.
6835980Sbostic 			 */
6935980Sbostic 			if (minlen == -1) {
7035980Sbostic 				p = argv[optind - 1];
7135980Sbostic 				if (p[0] == '-' && p[1] == ch && !p[2])
7235980Sbostic 					minlen = atoi(++p);
7335980Sbostic 				else
7435980Sbostic 					minlen = atoi(argv[optind] + 1);
751105Sbill 			}
7635980Sbostic 			break;
7735980Sbostic 		case '-':
7835980Sbostic 		case 'a':
7935980Sbostic 			asdata = 1;
8035980Sbostic 			break;
8149503Sbostic 		case 'f':
8249503Sbostic 			fflg = 1;
8349503Sbostic 			break;
8449503Sbostic 		case 'n':
8549503Sbostic 			minlen = atoi(optarg);
8649503Sbostic 			break;
8735980Sbostic 		case 'o':
8835980Sbostic 			oflg = 1;
8935980Sbostic 			break;
9035980Sbostic 		case '?':
9135980Sbostic 		default:
9249503Sbostic 			usage();
9335980Sbostic 		}
9435980Sbostic 	argc -= optind;
9535980Sbostic 	argv += optind;
9630142Sbostic 
9735980Sbostic 	if (minlen == -1)
9835980Sbostic 		minlen = DEF_LEN;
9935980Sbostic 
10049503Sbostic 	if (!(bfr = malloc((u_int)minlen))) {
10149503Sbostic 		(void)fprintf(stderr, "strings: %s\n", strerror(errno));
10235980Sbostic 		exit(1);
10330142Sbostic 	}
10435980Sbostic 	bfr[minlen] = '\0';
10549861Sbostic 	file = "stdin";
1061105Sbill 	do {
10730142Sbostic 		if (*argv) {
10847678Smarc 			file = *argv++;
10947678Smarc 			if (!freopen(file, "r", stdin)) {
11049503Sbostic 				(void)fprintf(stderr,
11150945Sbostic 				    "strings: %s: %s\n", file, strerror(errno));
11247678Smarc 				exitcode = 1;
11347678Smarc 				goto nextfile;
1141105Sbill 			}
1151105Sbill 		}
11630142Sbostic 		foff = 0;
11747678Smarc #define DO_EVERYTHING()		{read_len = -1; head_len = 0; goto start;}
11835980Sbostic 		read_len = -1;
11930142Sbostic 		if (asdata)
12047678Smarc 			DO_EVERYTHING()
12130142Sbostic 		else {
12230142Sbostic 			head = (EXEC *)hbfr;
12349503Sbostic 			if ((head_len =
12449503Sbostic 			    read(fileno(stdin), head, sizeof(EXEC))) == -1)
12547678Smarc 				DO_EVERYTHING()
12630142Sbostic 			if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
12749497Sdonn 				foff = N_TXTOFF(*head);
12849503Sbostic 				if (fseek(stdin, foff, SEEK_SET) == -1)
12947678Smarc 					DO_EVERYTHING()
13049497Sdonn 				read_len = head->a_text + head->a_data;
13130142Sbostic 				head_len = 0;
13230142Sbostic 			}
13330142Sbostic 			else
13430142Sbostic 				hcnt = 0;
1351105Sbill 		}
13647678Smarc start:
13735980Sbostic 		for (cnt = 0; (ch = getch()) != EOF;) {
13830142Sbostic 			if (ISSTR(ch)) {
13930142Sbostic 				if (!cnt)
14030142Sbostic 					C = bfr;
14130142Sbostic 				*C++ = ch;
14230142Sbostic 				if (++cnt < minlen)
14330142Sbostic 					continue;
14447678Smarc 				if (fflg)
14547678Smarc 					printf("%s:", file);
1461105Sbill 				if (oflg)
14749503Sbostic 					printf("%07ld %s",
14849503Sbostic 					    foff - minlen, (char *)bfr);
14930142Sbostic 				else
15049503Sbostic 					printf("%s", bfr);
15130142Sbostic 				while ((ch = getch()) != EOF && ISSTR(ch))
15230142Sbostic 					putchar((char)ch);
15330142Sbostic 				putchar('\n');
1541105Sbill 			}
15530142Sbostic 			cnt = 0;
1561105Sbill 		}
15747678Smarc nextfile: ;
15830142Sbostic 	} while (*argv);
15947678Smarc 	exit(exitcode);
1601105Sbill }
1611105Sbill 
16230142Sbostic /*
16330142Sbostic  * getch --
16430142Sbostic  *	get next character from wherever
16530142Sbostic  */
16630142Sbostic getch()
1671105Sbill {
16830142Sbostic 	++foff;
16930142Sbostic 	if (head_len) {
17030142Sbostic 		if (hcnt < head_len)
17130142Sbostic 			return((int)hbfr[hcnt++]);
17230142Sbostic 		head_len = 0;
1731105Sbill 	}
17435980Sbostic 	if (read_len == -1 || read_len-- > 0)
17530142Sbostic 		return(getchar());
17630142Sbostic 	return(EOF);
1771105Sbill }
17849503Sbostic 
17949503Sbostic static void
18049503Sbostic usage()
18149503Sbostic {
18249503Sbostic 	(void)fprintf(stderr,
18349503Sbostic 	    "usage: strings [-afo] [-n length] [file ... ]\n");
18449503Sbostic 	exit(1);
18549503Sbostic }
186