xref: /csrg-svn/usr.bin/strings/strings.c (revision 30142)
121577Sdist /*
221577Sdist  * Copyright (c) 1980 Regents of the University of California.
321577Sdist  * All rights reserved.  The Berkeley software License Agreement
421577Sdist  * specifies the terms and conditions for redistribution.
521577Sdist  */
621577Sdist 
717267Ssam #ifndef lint
821577Sdist char copyright[] =
921577Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1021577Sdist  All rights reserved.\n";
1121577Sdist #endif not lint
1217267Ssam 
1321577Sdist #ifndef lint
14*30142Sbostic static char sccsid[] = "@(#)strings.c	5.2 (Berkeley) 11/24/86";
1521577Sdist #endif not lint
1621577Sdist 
17*30142Sbostic #include <sys/types.h>
18*30142Sbostic #include <sys/file.h>
19*30142Sbostic #include <a.out.h>
201105Sbill #include <stdio.h>
211105Sbill #include <ctype.h>
221105Sbill 
23*30142Sbostic #define DEF_LEN		4		/* default minimum string length */
24*30142Sbostic #define EOS		(char)NULL	/* end of string */
25*30142Sbostic #define ERR		-1		/* general error */
26*30142Sbostic #define ERREXIT		1		/* error exit */
27*30142Sbostic #define NO		0		/* false/no */
28*30142Sbostic #define OK		0		/* ok exit */
29*30142Sbostic #define YES		1		/* true/yes */
301105Sbill 
31*30142Sbostic #define ISSTR(ch)	(isascii(ch) && (isprint(ch) || ch == '\t'))
321105Sbill 
33*30142Sbostic typedef struct exec	EXEC;		/* struct exec cast */
341105Sbill 
35*30142Sbostic static long	foff;			/* offset in the file */
36*30142Sbostic static int	hcnt,			/* head count */
37*30142Sbostic 		head_len,		/* length of header */
38*30142Sbostic 		read_len;		/* length to read */
39*30142Sbostic static u_char	hbfr[sizeof(EXEC)];	/* buffer for struct exec */
401105Sbill 
41*30142Sbostic main(argc,argv)
42*30142Sbostic int	argc;
43*30142Sbostic char	**argv;
441105Sbill {
45*30142Sbostic 	register int	ch,		/* character */
46*30142Sbostic 			cnt;		/* general counter */
47*30142Sbostic 	register u_char	*C;		/* bfr pointer */
48*30142Sbostic 	EXEC	*head;			/* exec header pointer */
49*30142Sbostic 	int	minlen = DEF_LEN;	/* minimum string length */
50*30142Sbostic 	short	asdata = NO,		/* look in everything */
51*30142Sbostic 		oflg;			/* print octal location */
52*30142Sbostic 	u_char	*bfr;			/* collection buffer */
53*30142Sbostic 	char	*file,			/* file name for error */
54*30142Sbostic 		*malloc();
551105Sbill 
56*30142Sbostic 	/*
57*30142Sbostic 	 * for backward compatibility, allow '-' to specify 'a' flag; no
58*30142Sbostic 	 * longer documented in the man page or usage string.
59*30142Sbostic 	 */
60*30142Sbostic 	for (++argv;*argv && **argv ==  '-';++argv) {
61*30142Sbostic 		for (cnt = 1;(*argv)[cnt];++cnt)
62*30142Sbostic 			switch ((*argv)[cnt]) {
63*30142Sbostic 				case 'a':
64*30142Sbostic 					asdata = YES;
65*30142Sbostic 					break;
66*30142Sbostic 				case 'o':
67*30142Sbostic 					oflg = YES;
68*30142Sbostic 					break;
69*30142Sbostic 				default:	/* getopt message compatible */
70*30142Sbostic 					if (!isdigit((*argv)[cnt])) {
71*30142Sbostic 						fprintf(stderr,"strings: illegal option -- %c\nusage: strings [-ao] [-#] [file ... ]\n",(*argv)[cnt]);
72*30142Sbostic 						exit(ERREXIT);
73*30142Sbostic 					}
74*30142Sbostic 					minlen = atoi(*argv + 1);
75*30142Sbostic 					break;
761105Sbill 			}
77*30142Sbostic 		if (cnt == 1)
78*30142Sbostic 			asdata = YES;
791105Sbill 	}
80*30142Sbostic 
81*30142Sbostic 	if (!(bfr = (u_char *)malloc((u_int)minlen))) {
82*30142Sbostic 		fputs("strings: unable to allocate space.\n",stderr);
83*30142Sbostic 		exit(ERREXIT);
84*30142Sbostic 	}
85*30142Sbostic 	bfr[minlen] = EOS;
86*30142Sbostic 	file = "stdin";
871105Sbill 	do {
88*30142Sbostic 		if (*argv) {
89*30142Sbostic 			if (!freopen(*argv,"r",stdin)) {
90*30142Sbostic 				perror(*argv);
91*30142Sbostic 				exit(ERREXIT);
921105Sbill 			}
93*30142Sbostic 			file = *argv++;
941105Sbill 		}
95*30142Sbostic 		foff = 0;
96*30142Sbostic 		read_len = ERR;
97*30142Sbostic 		if (asdata)
98*30142Sbostic 			head_len = 0;
99*30142Sbostic 		else {
100*30142Sbostic 			head = (EXEC *)hbfr;
101*30142Sbostic 			if ((head_len = read(fileno(stdin),(char *)head,sizeof(EXEC))) == ERR) {
102*30142Sbostic 				perror(file);
103*30142Sbostic 				exit(ERREXIT);
104*30142Sbostic 			}
105*30142Sbostic 			if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
106*30142Sbostic 				foff = N_TXTOFF(*head) + head->a_text;
107*30142Sbostic 				if (fseek(stdin,foff,L_SET) == ERR) {
108*30142Sbostic 					perror(file);
109*30142Sbostic 					exit(ERREXIT);
110*30142Sbostic 				}
111*30142Sbostic 				read_len = head->a_data;
112*30142Sbostic 				head_len = 0;
113*30142Sbostic 			}
114*30142Sbostic 			else
115*30142Sbostic 				hcnt = 0;
1161105Sbill 		}
117*30142Sbostic 		for (cnt = 0;(ch = getch()) != EOF;) {
118*30142Sbostic 			if (ISSTR(ch)) {
119*30142Sbostic 				if (!cnt)
120*30142Sbostic 					C = bfr;
121*30142Sbostic 				*C++ = ch;
122*30142Sbostic 				if (++cnt < minlen)
123*30142Sbostic 					continue;
1241105Sbill 				if (oflg)
125*30142Sbostic 					printf("%07lo %s",foff - minlen,bfr);
126*30142Sbostic 				else
127*30142Sbostic 					fputs((char *)bfr,stdout);
128*30142Sbostic 				while ((ch = getch()) != EOF && ISSTR(ch))
129*30142Sbostic 					putchar((char)ch);
130*30142Sbostic 				putchar('\n');
1311105Sbill 			}
132*30142Sbostic 			cnt = 0;
1331105Sbill 		}
134*30142Sbostic 	} while (*argv);
135*30142Sbostic 	exit(OK);
1361105Sbill }
1371105Sbill 
138*30142Sbostic /*
139*30142Sbostic  * getch --
140*30142Sbostic  *	get next character from wherever
141*30142Sbostic  */
142*30142Sbostic static
143*30142Sbostic getch()
1441105Sbill {
145*30142Sbostic 	++foff;
146*30142Sbostic 	if (head_len) {
147*30142Sbostic 		if (hcnt < head_len)
148*30142Sbostic 			return((int)hbfr[hcnt++]);
149*30142Sbostic 		head_len = 0;
1501105Sbill 	}
151*30142Sbostic 	if (read_len == ERR || read_len-- > 0)
152*30142Sbostic 		return(getchar());
153*30142Sbostic 	return(EOF);
1541105Sbill }
155