BSD 4_3_Reno release
[unix-history] / usr / src / pgrm / strings / strings.c
CommitLineData
22e155fc 1/*
f4ec6955
KB
2 * Copyright (c) 1980, 1987 The Regents of the University of California.
3 * All rights reserved.
4 *
1c15e888
C
5 * Redistribution and use in source and binary forms are permitted
6 * provided that: (1) source distributions retain this entire copyright
7 * notice and comment, and (2) distributions including binaries display
8 * the following acknowledgement: ``This product includes software
9 * developed by the University of California, Berkeley and its contributors''
10 * in the documentation or other materials provided with the distribution
11 * and in all advertising materials mentioning features or use of this
12 * software. Neither the name of the University nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22e155fc
DF
18 */
19
20#ifndef lint
21char copyright[] =
f4ec6955 22"@(#) Copyright (c) 1980, 1987 The Regents of the University of California.\n\
22e155fc 23 All rights reserved.\n";
f4ec6955 24#endif /* not lint */
22e155fc 25
052c3e48 26#ifndef lint
1c15e888 27static char sccsid[] = "@(#)strings.c 5.6 (Berkeley) 6/1/90";
f4ec6955 28#endif /* not lint */
052c3e48 29
76854072
KB
30#include <sys/types.h>
31#include <sys/file.h>
ca5a877f 32#include <a.out.h>
76854072 33#include <stdio.h>
ca5a877f
BJ
34#include <ctype.h>
35
76854072 36#define DEF_LEN 4 /* default minimum string length */
76854072 37#define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t'))
ca5a877f 38
76854072 39typedef struct exec EXEC; /* struct exec cast */
ca5a877f 40
76854072
KB
41static long foff; /* offset in the file */
42static int hcnt, /* head count */
43 head_len, /* length of header */
44 read_len; /* length to read */
45static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */
ca5a877f 46
f4ec6955
KB
47main(argc, argv)
48 int argc;
49 char **argv;
ca5a877f 50{
f4ec6955
KB
51 extern char *optarg;
52 extern int optind;
53 register int ch, cnt;
54 register u_char *C;
55 EXEC *head;
56 int minlen;
57 short asdata, oflg;
58 u_char *bfr;
59 char *file, *p, *malloc();
76854072
KB
60
61 /*
62 * for backward compatibility, allow '-' to specify 'a' flag; no
63 * longer documented in the man page or usage string.
64 */
6849ae63 65 asdata = oflg = 0;
f4ec6955
KB
66 minlen = -1;
67 while ((ch = getopt(argc, argv, "-0123456789ao")) != EOF)
68 switch((char)ch) {
69 case '0': case '1': case '2': case '3': case '4':
70 case '5': case '6': case '7': case '8': case '9':
71 /*
72 * kludge: strings was originally designed to take
73 * a number after a dash.
74 */
75 if (minlen == -1) {
76 p = argv[optind - 1];
77 if (p[0] == '-' && p[1] == ch && !p[2])
78 minlen = atoi(++p);
79 else
80 minlen = atoi(argv[optind] + 1);
ca5a877f 81 }
f4ec6955
KB
82 break;
83 case '-':
84 case 'a':
85 asdata = 1;
86 break;
87 case 'o':
88 oflg = 1;
89 break;
90 case '?':
91 default:
92 fprintf(stderr,
93 "usage: strings [-ao] [-#] [file ... ]\n");
94 exit(1);
95 }
96 argc -= optind;
97 argv += optind;
98
99 if (minlen == -1)
100 minlen = DEF_LEN;
76854072
KB
101
102 if (!(bfr = (u_char *)malloc((u_int)minlen))) {
f4ec6955
KB
103 fputs("strings: no space.\n", stderr);
104 exit(1);
ca5a877f 105 }
f4ec6955 106 bfr[minlen] = '\0';
76854072 107 file = "stdin";
ca5a877f 108 do {
76854072 109 if (*argv) {
f4ec6955 110 if (!freopen(*argv, "r", stdin)) {
76854072 111 perror(*argv);
f4ec6955 112 exit(1);
ca5a877f 113 }
76854072 114 file = *argv++;
ca5a877f 115 }
76854072 116 foff = 0;
f4ec6955 117 read_len = -1;
76854072
KB
118 if (asdata)
119 head_len = 0;
120 else {
121 head = (EXEC *)hbfr;
f4ec6955 122 if ((head_len = read(fileno(stdin), (char *)head, sizeof(EXEC))) == -1) {
76854072 123 perror(file);
f4ec6955 124 exit(1);
76854072
KB
125 }
126 if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) {
127 foff = N_TXTOFF(*head) + head->a_text;
f4ec6955 128 if (fseek(stdin, foff, L_SET) == -1) {
76854072 129 perror(file);
f4ec6955 130 exit(1);
76854072
KB
131 }
132 read_len = head->a_data;
133 head_len = 0;
134 }
135 else
136 hcnt = 0;
ca5a877f 137 }
f4ec6955 138 for (cnt = 0; (ch = getch()) != EOF;) {
76854072
KB
139 if (ISSTR(ch)) {
140 if (!cnt)
141 C = bfr;
142 *C++ = ch;
143 if (++cnt < minlen)
144 continue;
ca5a877f 145 if (oflg)
f4ec6955
KB
146 printf("%07ld %s", foff - minlen,
147 (char *)bfr);
76854072 148 else
f4ec6955 149 fputs((char *)bfr, stdout);
76854072
KB
150 while ((ch = getch()) != EOF && ISSTR(ch))
151 putchar((char)ch);
152 putchar('\n');
ca5a877f 153 }
76854072 154 cnt = 0;
ca5a877f 155 }
76854072 156 } while (*argv);
f4ec6955 157 exit(0);
ca5a877f
BJ
158}
159
76854072
KB
160/*
161 * getch --
162 * get next character from wherever
163 */
76854072 164getch()
ca5a877f 165{
76854072
KB
166 ++foff;
167 if (head_len) {
168 if (hcnt < head_len)
169 return((int)hbfr[hcnt++]);
170 head_len = 0;
ca5a877f 171 }
f4ec6955 172 if (read_len == -1 || read_len-- > 0)
76854072
KB
173 return(getchar());
174 return(EOF);
ca5a877f 175}