xref: /csrg-svn/usr.bin/strings/strings.c (revision 35980)
121577Sdist /*
2*35980Sbostic  * Copyright (c) 1980, 1987 The Regents of the University of California.
3*35980Sbostic  * All rights reserved.
4*35980Sbostic  *
5*35980Sbostic  * Redistribution and use in source and binary forms are permitted
6*35980Sbostic  * provided that the above copyright notice and this paragraph are
7*35980Sbostic  * duplicated in all such forms and that any documentation,
8*35980Sbostic  * advertising materials, and other materials related to such
9*35980Sbostic  * distribution and use acknowledge that the software was developed
10*35980Sbostic  * by the University of California, Berkeley.  The name of the
11*35980Sbostic  * University may not be used to endorse or promote products derived
12*35980Sbostic  * from this software without specific prior written permission.
13*35980Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*35980Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*35980Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621577Sdist  */
1721577Sdist 
1817267Ssam #ifndef lint
1921577Sdist char copyright[] =
20*35980Sbostic "@(#) Copyright (c) 1980, 1987 The Regents of the University of California.\n\
2121577Sdist  All rights reserved.\n";
22*35980Sbostic #endif /* not lint */
2317267Ssam 
2421577Sdist #ifndef lint
25*35980Sbostic static char sccsid[] = "@(#)strings.c	5.4 (Berkeley) 10/21/88";
26*35980Sbostic #endif /* not lint */
2721577Sdist 
2830142Sbostic #include <sys/types.h>
2930142Sbostic #include <sys/file.h>
3030142Sbostic #include <a.out.h>
311105Sbill #include <stdio.h>
321105Sbill #include <ctype.h>
331105Sbill 
3430142Sbostic #define DEF_LEN		4		/* default minimum string length */
3530142Sbostic #define ISSTR(ch)	(isascii(ch) && (isprint(ch) || ch == '\t'))
361105Sbill 
3730142Sbostic typedef struct exec	EXEC;		/* struct exec cast */
381105Sbill 
3930142Sbostic static long	foff;			/* offset in the file */
4030142Sbostic static int	hcnt,			/* head count */
4130142Sbostic 		head_len,		/* length of header */
4230142Sbostic 		read_len;		/* length to read */
4330142Sbostic static u_char	hbfr[sizeof(EXEC)];	/* buffer for struct exec */
441105Sbill 
45*35980Sbostic main(argc, argv)
46*35980Sbostic 	int argc;
47*35980Sbostic 	char **argv;
481105Sbill {
49*35980Sbostic 	extern char *optarg;
50*35980Sbostic 	extern int optind;
51*35980Sbostic 	register int ch, cnt;
52*35980Sbostic 	register u_char *C;
53*35980Sbostic 	EXEC *head;
54*35980Sbostic 	int minlen;
55*35980Sbostic 	short asdata, oflg;
56*35980Sbostic 	u_char *bfr;
57*35980Sbostic 	char *file, *p, *malloc();
581105Sbill 
5930142Sbostic 	/*
6030142Sbostic 	 * for backward compatibility, allow '-' to specify 'a' flag; no
6130142Sbostic 	 * longer documented in the man page or usage string.
6230142Sbostic 	 */
63*35980Sbostic 	asdata = 0;
64*35980Sbostic 	minlen = -1;
65*35980Sbostic 	while ((ch = getopt(argc, argv, "-0123456789ao")) != EOF)
66*35980Sbostic 		switch((char)ch) {
67*35980Sbostic 		case '0': case '1': case '2': case '3': case '4':
68*35980Sbostic 		case '5': case '6': case '7': case '8': case '9':
69*35980Sbostic 			/*
70*35980Sbostic 			 * kludge: strings was originally designed to take
71*35980Sbostic 			 * a number after a dash.
72*35980Sbostic 			 */
73*35980Sbostic 			if (minlen == -1) {
74*35980Sbostic 				p = argv[optind - 1];
75*35980Sbostic 				if (p[0] == '-' && p[1] == ch && !p[2])
76*35980Sbostic 					minlen = atoi(++p);
77*35980Sbostic 				else
78*35980Sbostic 					minlen = atoi(argv[optind] + 1);
791105Sbill 			}
80*35980Sbostic 			break;
81*35980Sbostic 		case '-':
82*35980Sbostic 		case 'a':
83*35980Sbostic 			asdata = 1;
84*35980Sbostic 			break;
85*35980Sbostic 		case 'o':
86*35980Sbostic 			oflg = 1;
87*35980Sbostic 			break;
88*35980Sbostic 		case '?':
89*35980Sbostic 		default:
90*35980Sbostic 			fprintf(stderr,
91*35980Sbostic 			    "usage: strings [-ao] [-#] [file ... ]\n");
92*35980Sbostic 			exit(1);
93*35980Sbostic 		}
94*35980Sbostic 	argc -= optind;
95*35980Sbostic 	argv += optind;
9630142Sbostic 
97*35980Sbostic 	if (minlen == -1)
98*35980Sbostic 		minlen = DEF_LEN;
99*35980Sbostic 
10030142Sbostic 	if (!(bfr = (u_char *)malloc((u_int)minlen))) {
101*35980Sbostic 		fputs("strings: no space.\n", stderr);
102*35980Sbostic 		exit(1);
10330142Sbostic 	}
104*35980Sbostic 	bfr[minlen] = '\0';
10530142Sbostic 	file = "stdin";
1061105Sbill 	do {
10730142Sbostic 		if (*argv) {
108*35980Sbostic 			if (!freopen(*argv, "r", stdin)) {
10930142Sbostic 				perror(*argv);
110*35980Sbostic 				exit(1);
1111105Sbill 			}
11230142Sbostic 			file = *argv++;
1131105Sbill 		}
11430142Sbostic 		foff = 0;
115*35980Sbostic 		read_len = -1;
11630142Sbostic 		if (asdata)
11730142Sbostic 			head_len = 0;
11830142Sbostic 		else {
11930142Sbostic 			head = (EXEC *)hbfr;
120*35980Sbostic 			if ((head_len = read(fileno(stdin), (char *)head, sizeof(EXEC))) == -1) {
12130142Sbostic 				perror(file);
122*35980Sbostic 				exit(1);
12330142Sbostic 			}
12430142Sbostic 			if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
12530142Sbostic 				foff = N_TXTOFF(*head) + head->a_text;
126*35980Sbostic 				if (fseek(stdin, foff, L_SET) == -1) {
12730142Sbostic 					perror(file);
128*35980Sbostic 					exit(1);
12930142Sbostic 				}
13030142Sbostic 				read_len = head->a_data;
13130142Sbostic 				head_len = 0;
13230142Sbostic 			}
13330142Sbostic 			else
13430142Sbostic 				hcnt = 0;
1351105Sbill 		}
136*35980Sbostic 		for (cnt = 0; (ch = getch()) != EOF;) {
13730142Sbostic 			if (ISSTR(ch)) {
13830142Sbostic 				if (!cnt)
13930142Sbostic 					C = bfr;
14030142Sbostic 				*C++ = ch;
14130142Sbostic 				if (++cnt < minlen)
14230142Sbostic 					continue;
1431105Sbill 				if (oflg)
144*35980Sbostic 					printf("%07ld %s", foff - minlen,
145*35980Sbostic 					    (char *)bfr);
14630142Sbostic 				else
147*35980Sbostic 					fputs((char *)bfr, stdout);
14830142Sbostic 				while ((ch = getch()) != EOF && ISSTR(ch))
14930142Sbostic 					putchar((char)ch);
15030142Sbostic 				putchar('\n');
1511105Sbill 			}
15230142Sbostic 			cnt = 0;
1531105Sbill 		}
15430142Sbostic 	} while (*argv);
155*35980Sbostic 	exit(0);
1561105Sbill }
1571105Sbill 
15830142Sbostic /*
15930142Sbostic  * getch --
16030142Sbostic  *	get next character from wherever
16130142Sbostic  */
16230142Sbostic getch()
1631105Sbill {
16430142Sbostic 	++foff;
16530142Sbostic 	if (head_len) {
16630142Sbostic 		if (hcnt < head_len)
16730142Sbostic 			return((int)hbfr[hcnt++]);
16830142Sbostic 		head_len = 0;
1691105Sbill 	}
170*35980Sbostic 	if (read_len == -1 || read_len-- > 0)
17130142Sbostic 		return(getchar());
17230142Sbostic 	return(EOF);
1731105Sbill }
174