Commit | Line | Data |
---|---|---|
95f51977 C |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
8 | char copyright[] = | |
9 | "@(#) Copyright (c) 1980 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
11 | #endif not lint | |
12 | ||
13 | #ifndef lint | |
ca67e7b4 | 14 | static char sccsid[] = "@(#)strings.c 5.3 (Berkeley) 12/3/86"; |
95f51977 C |
15 | #endif not lint |
16 | ||
ca67e7b4 C |
17 | #include <sys/types.h> |
18 | #include <sys/file.h> | |
ca5a877f | 19 | #include <a.out.h> |
ca67e7b4 | 20 | #include <stdio.h> |
ca5a877f BJ |
21 | #include <ctype.h> |
22 | ||
ca67e7b4 C |
23 | #define DEF_LEN 4 /* default minimum string length */ |
24 | #define EOS (char)NULL /* end of string */ | |
25 | #define ERR -1 /* general error */ | |
26 | #define ERREXIT 1 /* error exit */ | |
27 | #define NO 0 /* false/no */ | |
28 | #define OK 0 /* ok exit */ | |
29 | #define YES 1 /* true/yes */ | |
ca5a877f | 30 | |
ca67e7b4 | 31 | #define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t')) |
ca5a877f | 32 | |
ca67e7b4 | 33 | typedef struct exec EXEC; /* struct exec cast */ |
ca5a877f | 34 | |
ca67e7b4 C |
35 | static long foff; /* offset in the file */ |
36 | static int hcnt, /* head count */ | |
37 | head_len, /* length of header */ | |
38 | read_len; /* length to read */ | |
39 | static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */ | |
ca5a877f | 40 | |
ca67e7b4 C |
41 | main(argc,argv) |
42 | int argc; | |
43 | char **argv; | |
ca5a877f | 44 | { |
ca67e7b4 C |
45 | register int ch, /* character */ |
46 | cnt; /* general counter */ | |
47 | register u_char *C; /* bfr pointer */ | |
48 | EXEC *head; /* exec header pointer */ | |
49 | int minlen = DEF_LEN; /* minimum string length */ | |
50 | short asdata = NO, /* look in everything */ | |
51 | oflg; /* print octal location */ | |
52 | u_char *bfr; /* collection buffer */ | |
53 | char *file, /* file name for error */ | |
54 | *malloc(); | |
55 | ||
56 | /* | |
57 | * for backward compatibility, allow '-' to specify 'a' flag; no | |
58 | * longer documented in the man page or usage string. | |
59 | */ | |
60 | for (++argv;*argv && **argv == '-';++argv) { | |
61 | for (cnt = 1;(*argv)[cnt];++cnt) | |
62 | switch ((*argv)[cnt]) { | |
63 | case 'a': | |
64 | asdata = YES; | |
65 | break; | |
66 | case 'o': | |
67 | oflg = YES; | |
68 | break; | |
69 | default: /* getopt message compatible */ | |
70 | if (!isdigit((*argv)[cnt])) { | |
71 | fprintf(stderr,"strings: illegal option -- %c\nusage: strings [-ao] [-#] [file ... ]\n",(*argv)[cnt]); | |
72 | exit(ERREXIT); | |
73 | } | |
74 | minlen = atoi(*argv + 1); | |
75 | break; | |
ca5a877f | 76 | } |
ca67e7b4 C |
77 | if (cnt == 1) |
78 | asdata = YES; | |
79 | } | |
80 | ||
81 | if (!(bfr = (u_char *)malloc((u_int)minlen))) { | |
82 | fputs("strings: unable to allocate space.\n",stderr); | |
83 | exit(ERREXIT); | |
ca5a877f | 84 | } |
ca67e7b4 C |
85 | bfr[minlen] = EOS; |
86 | file = "stdin"; | |
ca5a877f | 87 | do { |
ca67e7b4 C |
88 | if (*argv) { |
89 | if (!freopen(*argv,"r",stdin)) { | |
90 | perror(*argv); | |
91 | exit(ERREXIT); | |
ca5a877f | 92 | } |
ca67e7b4 | 93 | file = *argv++; |
ca5a877f | 94 | } |
ca67e7b4 C |
95 | foff = 0; |
96 | read_len = ERR; | |
97 | if (asdata) | |
98 | head_len = 0; | |
99 | else { | |
100 | head = (EXEC *)hbfr; | |
101 | if ((head_len = read(fileno(stdin),(char *)head,sizeof(EXEC))) == ERR) { | |
102 | perror(file); | |
103 | exit(ERREXIT); | |
104 | } | |
105 | if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) { | |
106 | foff = N_TXTOFF(*head) + head->a_text; | |
107 | if (fseek(stdin,foff,L_SET) == ERR) { | |
108 | perror(file); | |
109 | exit(ERREXIT); | |
110 | } | |
111 | read_len = head->a_data; | |
112 | head_len = 0; | |
113 | } | |
114 | else | |
115 | hcnt = 0; | |
ca5a877f | 116 | } |
ca67e7b4 C |
117 | for (cnt = 0;(ch = getch()) != EOF;) { |
118 | if (ISSTR(ch)) { | |
119 | if (!cnt) | |
120 | C = bfr; | |
121 | *C++ = ch; | |
122 | if (++cnt < minlen) | |
123 | continue; | |
ca5a877f | 124 | if (oflg) |
ca67e7b4 C |
125 | printf("%07ld %s",foff - minlen,bfr); |
126 | else | |
127 | fputs((char *)bfr,stdout); | |
128 | while ((ch = getch()) != EOF && ISSTR(ch)) | |
129 | putchar((char)ch); | |
130 | putchar('\n'); | |
ca5a877f | 131 | } |
ca67e7b4 | 132 | cnt = 0; |
ca5a877f | 133 | } |
ca67e7b4 C |
134 | } while (*argv); |
135 | exit(OK); | |
ca5a877f BJ |
136 | } |
137 | ||
ca67e7b4 C |
138 | /* |
139 | * getch -- | |
140 | * get next character from wherever | |
141 | */ | |
142 | static | |
143 | getch() | |
ca5a877f | 144 | { |
ca67e7b4 C |
145 | ++foff; |
146 | if (head_len) { | |
147 | if (hcnt < head_len) | |
148 | return((int)hbfr[hcnt++]); | |
149 | head_len = 0; | |
ca5a877f | 150 | } |
ca67e7b4 C |
151 | if (read_len == ERR || read_len-- > 0) |
152 | return(getchar()); | |
153 | return(EOF); | |
ca5a877f | 154 | } |