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