1 /* 2 * Copyright (c) 1980, 1987 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980, 1987 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)strings.c 5.7 (Berkeley) 03/28/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/file.h> 20 #include <a.out.h> 21 #include <stdio.h> 22 #include <ctype.h> 23 24 #define DEF_LEN 4 /* default minimum string length */ 25 #define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t')) 26 27 typedef struct exec EXEC; /* struct exec cast */ 28 29 static long foff; /* offset in the file */ 30 static int hcnt, /* head count */ 31 head_len, /* length of header */ 32 read_len; /* length to read */ 33 static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */ 34 35 main(argc, argv) 36 int argc; 37 char **argv; 38 { 39 extern char *optarg; 40 extern int optind; 41 register int ch, cnt; 42 register u_char *C; 43 EXEC *head; 44 int minlen; 45 int exitcode = 0; 46 short asdata, oflg, fflg; 47 u_char *bfr; 48 char *file, *p, *malloc(); 49 50 /* 51 * for backward compatibility, allow '-' to specify 'a' flag; no 52 * longer documented in the man page or usage string. 53 */ 54 asdata = oflg = fflg = 0; 55 minlen = -1; 56 while ((ch = getopt(argc, argv, "-0123456789aof")) != EOF) 57 switch((char)ch) { 58 case '0': case '1': case '2': case '3': case '4': 59 case '5': case '6': case '7': case '8': case '9': 60 /* 61 * kludge: strings was originally designed to take 62 * a number after a dash. 63 */ 64 if (minlen == -1) { 65 p = argv[optind - 1]; 66 if (p[0] == '-' && p[1] == ch && !p[2]) 67 minlen = atoi(++p); 68 else 69 minlen = atoi(argv[optind] + 1); 70 } 71 break; 72 case '-': 73 case 'a': 74 asdata = 1; 75 break; 76 case 'o': 77 oflg = 1; 78 break; 79 case 'f': 80 fflg = 1; 81 break; 82 case '?': 83 default: 84 fprintf(stderr, 85 "usage: strings [-ao] [-#] [file ... ]\n"); 86 exit(1); 87 } 88 argc -= optind; 89 argv += optind; 90 91 if (minlen == -1) 92 minlen = DEF_LEN; 93 94 if (!(bfr = (u_char *)malloc((u_int)minlen))) { 95 fputs("strings: no space.\n", stderr); 96 exit(1); 97 } 98 bfr[minlen] = '\0'; 99 file = NULL; 100 do { 101 if (*argv) { 102 file = *argv++; 103 if (!freopen(file, "r", stdin)) { 104 perror(file); 105 exitcode = 1; 106 goto nextfile; 107 } 108 } 109 foff = 0; 110 #define DO_EVERYTHING() {read_len = -1; head_len = 0; goto start;} 111 read_len = -1; 112 if (asdata) 113 DO_EVERYTHING() 114 else { 115 head = (EXEC *)hbfr; 116 if ((head_len = read(fileno(stdin), (char *)head, sizeof(EXEC))) == -1) 117 DO_EVERYTHING() 118 if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) { 119 foff = N_TXTOFF(*head) + head->a_text; 120 if (fseek(stdin, foff, L_SET) == -1) 121 DO_EVERYTHING() 122 read_len = head->a_data; 123 head_len = 0; 124 } 125 else 126 hcnt = 0; 127 } 128 start: 129 for (cnt = 0; (ch = getch()) != EOF;) { 130 if (ISSTR(ch)) { 131 if (!cnt) 132 C = bfr; 133 *C++ = ch; 134 if (++cnt < minlen) 135 continue; 136 if (fflg) 137 printf("%s:", file); 138 if (oflg) 139 printf("%07ld %s", foff - minlen, 140 (char *)bfr); 141 else 142 fputs((char *)bfr, stdout); 143 while ((ch = getch()) != EOF && ISSTR(ch)) 144 putchar((char)ch); 145 putchar('\n'); 146 } 147 cnt = 0; 148 } 149 nextfile: ; 150 } while (*argv); 151 exit(exitcode); 152 } 153 154 /* 155 * getch -- 156 * get next character from wherever 157 */ 158 getch() 159 { 160 ++foff; 161 if (head_len) { 162 if (hcnt < head_len) 163 return((int)hbfr[hcnt++]); 164 head_len = 0; 165 } 166 if (read_len == -1 || read_len-- > 0) 167 return(getchar()); 168 return(EOF); 169 } 170