xref: /csrg-svn/usr.bin/strings/strings.c (revision 49497)
121577Sdist /*
235980Sbostic  * Copyright (c) 1980, 1987 The Regents of the University of California.
335980Sbostic  * All rights reserved.
435980Sbostic  *
542691Sbostic  * %sccs.include.redist.c%
621577Sdist  */
721577Sdist 
817267Ssam #ifndef lint
921577Sdist char copyright[] =
1035980Sbostic "@(#) Copyright (c) 1980, 1987 The Regents of the University of California.\n\
1121577Sdist  All rights reserved.\n";
1235980Sbostic #endif /* not lint */
1317267Ssam 
1421577Sdist #ifndef lint
15*49497Sdonn static char sccsid[] = "@(#)strings.c	5.8 (Berkeley) 05/09/91";
1635980Sbostic #endif /* not lint */
1721577Sdist 
1830142Sbostic #include <sys/types.h>
1930142Sbostic #include <sys/file.h>
2030142Sbostic #include <a.out.h>
211105Sbill #include <stdio.h>
221105Sbill #include <ctype.h>
231105Sbill 
2430142Sbostic #define DEF_LEN		4		/* default minimum string length */
2530142Sbostic #define ISSTR(ch)	(isascii(ch) && (isprint(ch) || ch == '\t'))
261105Sbill 
2730142Sbostic typedef struct exec	EXEC;		/* struct exec cast */
281105Sbill 
2930142Sbostic static long	foff;			/* offset in the file */
3030142Sbostic static int	hcnt,			/* head count */
3130142Sbostic 		head_len,		/* length of header */
3230142Sbostic 		read_len;		/* length to read */
3330142Sbostic static u_char	hbfr[sizeof(EXEC)];	/* buffer for struct exec */
341105Sbill 
3535980Sbostic main(argc, argv)
3635980Sbostic 	int argc;
3735980Sbostic 	char **argv;
381105Sbill {
3935980Sbostic 	extern char *optarg;
4035980Sbostic 	extern int optind;
4135980Sbostic 	register int ch, cnt;
4235980Sbostic 	register u_char *C;
4335980Sbostic 	EXEC *head;
4435980Sbostic 	int minlen;
4547678Smarc 	int exitcode = 0;
4647678Smarc 	short asdata, oflg, fflg;
4735980Sbostic 	u_char *bfr;
4835980Sbostic 	char *file, *p, *malloc();
491105Sbill 
5030142Sbostic 	/*
5130142Sbostic 	 * for backward compatibility, allow '-' to specify 'a' flag; no
5230142Sbostic 	 * longer documented in the man page or usage string.
5330142Sbostic 	 */
5447678Smarc 	asdata = oflg = fflg = 0;
5535980Sbostic 	minlen = -1;
5647678Smarc 	while ((ch = getopt(argc, argv, "-0123456789aof")) != EOF)
5735980Sbostic 		switch((char)ch) {
5835980Sbostic 		case '0': case '1': case '2': case '3': case '4':
5935980Sbostic 		case '5': case '6': case '7': case '8': case '9':
6035980Sbostic 			/*
6135980Sbostic 			 * kludge: strings was originally designed to take
6235980Sbostic 			 * a number after a dash.
6335980Sbostic 			 */
6435980Sbostic 			if (minlen == -1) {
6535980Sbostic 				p = argv[optind - 1];
6635980Sbostic 				if (p[0] == '-' && p[1] == ch && !p[2])
6735980Sbostic 					minlen = atoi(++p);
6835980Sbostic 				else
6935980Sbostic 					minlen = atoi(argv[optind] + 1);
701105Sbill 			}
7135980Sbostic 			break;
7235980Sbostic 		case '-':
7335980Sbostic 		case 'a':
7435980Sbostic 			asdata = 1;
7535980Sbostic 			break;
7635980Sbostic 		case 'o':
7735980Sbostic 			oflg = 1;
7835980Sbostic 			break;
7947678Smarc 		case 'f':
8047678Smarc 			fflg = 1;
8147678Smarc 			break;
8235980Sbostic 		case '?':
8335980Sbostic 		default:
8435980Sbostic 			fprintf(stderr,
8535980Sbostic 			    "usage: strings [-ao] [-#] [file ... ]\n");
8635980Sbostic 			exit(1);
8735980Sbostic 		}
8835980Sbostic 	argc -= optind;
8935980Sbostic 	argv += optind;
9030142Sbostic 
9135980Sbostic 	if (minlen == -1)
9235980Sbostic 		minlen = DEF_LEN;
9335980Sbostic 
9430142Sbostic 	if (!(bfr = (u_char *)malloc((u_int)minlen))) {
9535980Sbostic 		fputs("strings: no space.\n", stderr);
9635980Sbostic 		exit(1);
9730142Sbostic 	}
9835980Sbostic 	bfr[minlen] = '\0';
9947678Smarc 	file = NULL;
1001105Sbill 	do {
10130142Sbostic 		if (*argv) {
10247678Smarc 			file = *argv++;
10347678Smarc 			if (!freopen(file, "r", stdin)) {
10447678Smarc 				perror(file);
10547678Smarc 				exitcode = 1;
10647678Smarc 				goto nextfile;
1071105Sbill 			}
1081105Sbill 		}
10930142Sbostic 		foff = 0;
11047678Smarc #define DO_EVERYTHING()		{read_len = -1; head_len = 0; goto start;}
11135980Sbostic 		read_len = -1;
11230142Sbostic 		if (asdata)
11347678Smarc 			DO_EVERYTHING()
11430142Sbostic 		else {
11530142Sbostic 			head = (EXEC *)hbfr;
11647678Smarc 			if ((head_len = read(fileno(stdin), (char *)head, sizeof(EXEC))) == -1)
11747678Smarc 				DO_EVERYTHING()
11830142Sbostic 			if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
119*49497Sdonn 				foff = N_TXTOFF(*head);
12047678Smarc 				if (fseek(stdin, foff, L_SET) == -1)
12147678Smarc 					DO_EVERYTHING()
122*49497Sdonn 				read_len = head->a_text + head->a_data;
12330142Sbostic 				head_len = 0;
12430142Sbostic 			}
12530142Sbostic 			else
12630142Sbostic 				hcnt = 0;
1271105Sbill 		}
12847678Smarc start:
12935980Sbostic 		for (cnt = 0; (ch = getch()) != EOF;) {
13030142Sbostic 			if (ISSTR(ch)) {
13130142Sbostic 				if (!cnt)
13230142Sbostic 					C = bfr;
13330142Sbostic 				*C++ = ch;
13430142Sbostic 				if (++cnt < minlen)
13530142Sbostic 					continue;
13647678Smarc 				if (fflg)
13747678Smarc 					printf("%s:", file);
1381105Sbill 				if (oflg)
13935980Sbostic 					printf("%07ld %s", foff - minlen,
14035980Sbostic 					    (char *)bfr);
14130142Sbostic 				else
14235980Sbostic 					fputs((char *)bfr, stdout);
14330142Sbostic 				while ((ch = getch()) != EOF && ISSTR(ch))
14430142Sbostic 					putchar((char)ch);
14530142Sbostic 				putchar('\n');
1461105Sbill 			}
14730142Sbostic 			cnt = 0;
1481105Sbill 		}
14947678Smarc nextfile: ;
15030142Sbostic 	} while (*argv);
15147678Smarc 	exit(exitcode);
1521105Sbill }
1531105Sbill 
15430142Sbostic /*
15530142Sbostic  * getch --
15630142Sbostic  *	get next character from wherever
15730142Sbostic  */
15830142Sbostic getch()
1591105Sbill {
16030142Sbostic 	++foff;
16130142Sbostic 	if (head_len) {
16230142Sbostic 		if (hcnt < head_len)
16330142Sbostic 			return((int)hbfr[hcnt++]);
16430142Sbostic 		head_len = 0;
1651105Sbill 	}
16635980Sbostic 	if (read_len == -1 || read_len-- > 0)
16730142Sbostic 		return(getchar());
16830142Sbostic 	return(EOF);
1691105Sbill }
170