121577Sdist /* 235980Sbostic * Copyright (c) 1980, 1987 The Regents of the University of California. 335980Sbostic * All rights reserved. 435980Sbostic * 542691Sbostic * %sccs.include.redist.c% 621577Sdist */ 721577Sdist 817267Ssam #ifndef lint 921577Sdist char copyright[] = 1035980Sbostic "@(#) Copyright (c) 1980, 1987 The Regents of the University of California.\n\ 1121577Sdist All rights reserved.\n"; 1235980Sbostic #endif /* not lint */ 1317267Ssam 1421577Sdist #ifndef lint 15*49503Sbostic static char sccsid[] = "@(#)strings.c 5.9 (Berkeley) 05/09/91"; 1635980Sbostic #endif /* not lint */ 1721577Sdist 1830142Sbostic #include <sys/types.h> 19*49503Sbostic #include <fcntl.h> 20*49503Sbostic #include <errno.h> 2130142Sbostic #include <a.out.h> 22*49503Sbostic #include <unistd.h> 231105Sbill #include <stdio.h> 241105Sbill #include <ctype.h> 25*49503Sbostic #include <stdlib.h> 26*49503Sbostic #include <string.h> 271105Sbill 2830142Sbostic #define DEF_LEN 4 /* default minimum string length */ 2930142Sbostic #define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t')) 301105Sbill 3130142Sbostic typedef struct exec EXEC; /* struct exec cast */ 321105Sbill 3330142Sbostic static long foff; /* offset in the file */ 3430142Sbostic static int hcnt, /* head count */ 3530142Sbostic head_len, /* length of header */ 3630142Sbostic read_len; /* length to read */ 3730142Sbostic static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */ 381105Sbill 39*49503Sbostic static void usage(); 40*49503Sbostic 4135980Sbostic main(argc, argv) 4235980Sbostic int argc; 4335980Sbostic char **argv; 441105Sbill { 4535980Sbostic extern char *optarg; 4635980Sbostic extern int optind; 4735980Sbostic register int ch, cnt; 4835980Sbostic register u_char *C; 4935980Sbostic EXEC *head; 50*49503Sbostic int exitcode, minlen; 5147678Smarc short asdata, oflg, fflg; 5235980Sbostic u_char *bfr; 53*49503Sbostic char *file, *p; 541105Sbill 5530142Sbostic /* 5630142Sbostic * for backward compatibility, allow '-' to specify 'a' flag; no 5730142Sbostic * longer documented in the man page or usage string. 5830142Sbostic */ 59*49503Sbostic asdata = exitcode = fflg = oflg = 0; 6035980Sbostic minlen = -1; 61*49503Sbostic while ((ch = getopt(argc, argv, "-0123456789anof")) != EOF) 6235980Sbostic switch((char)ch) { 6335980Sbostic case '0': case '1': case '2': case '3': case '4': 6435980Sbostic case '5': case '6': case '7': case '8': case '9': 6535980Sbostic /* 6635980Sbostic * kludge: strings was originally designed to take 6735980Sbostic * a number after a dash. 6835980Sbostic */ 6935980Sbostic if (minlen == -1) { 7035980Sbostic p = argv[optind - 1]; 7135980Sbostic if (p[0] == '-' && p[1] == ch && !p[2]) 7235980Sbostic minlen = atoi(++p); 7335980Sbostic else 7435980Sbostic minlen = atoi(argv[optind] + 1); 751105Sbill } 7635980Sbostic break; 7735980Sbostic case '-': 7835980Sbostic case 'a': 7935980Sbostic asdata = 1; 8035980Sbostic break; 81*49503Sbostic case 'f': 82*49503Sbostic fflg = 1; 83*49503Sbostic break; 84*49503Sbostic case 'n': 85*49503Sbostic minlen = atoi(optarg); 86*49503Sbostic break; 8735980Sbostic case 'o': 8835980Sbostic oflg = 1; 8935980Sbostic break; 9035980Sbostic case '?': 9135980Sbostic default: 92*49503Sbostic usage(); 9335980Sbostic } 9435980Sbostic argc -= optind; 9535980Sbostic argv += optind; 9630142Sbostic 9735980Sbostic if (minlen == -1) 9835980Sbostic minlen = DEF_LEN; 9935980Sbostic 100*49503Sbostic if (!(bfr = malloc((u_int)minlen))) { 101*49503Sbostic (void)fprintf(stderr, "strings: %s\n", strerror(errno)); 10235980Sbostic exit(1); 10330142Sbostic } 10435980Sbostic bfr[minlen] = '\0'; 10547678Smarc file = NULL; 1061105Sbill do { 10730142Sbostic if (*argv) { 10847678Smarc file = *argv++; 10947678Smarc if (!freopen(file, "r", stdin)) { 110*49503Sbostic (void)fprintf(stderr, 111*49503Sbostic "strings; %s: %s\n", file, strerror(errno)); 11247678Smarc exitcode = 1; 11347678Smarc goto nextfile; 1141105Sbill } 1151105Sbill } 11630142Sbostic foff = 0; 11747678Smarc #define DO_EVERYTHING() {read_len = -1; head_len = 0; goto start;} 11835980Sbostic read_len = -1; 11930142Sbostic if (asdata) 12047678Smarc DO_EVERYTHING() 12130142Sbostic else { 12230142Sbostic head = (EXEC *)hbfr; 123*49503Sbostic if ((head_len = 124*49503Sbostic read(fileno(stdin), head, sizeof(EXEC))) == -1) 12547678Smarc DO_EVERYTHING() 12630142Sbostic if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) { 12749497Sdonn foff = N_TXTOFF(*head); 128*49503Sbostic if (fseek(stdin, foff, SEEK_SET) == -1) 12947678Smarc DO_EVERYTHING() 13049497Sdonn read_len = head->a_text + head->a_data; 13130142Sbostic head_len = 0; 13230142Sbostic } 13330142Sbostic else 13430142Sbostic hcnt = 0; 1351105Sbill } 13647678Smarc start: 13735980Sbostic for (cnt = 0; (ch = getch()) != EOF;) { 13830142Sbostic if (ISSTR(ch)) { 13930142Sbostic if (!cnt) 14030142Sbostic C = bfr; 14130142Sbostic *C++ = ch; 14230142Sbostic if (++cnt < minlen) 14330142Sbostic continue; 14447678Smarc if (fflg) 14547678Smarc printf("%s:", file); 1461105Sbill if (oflg) 147*49503Sbostic printf("%07ld %s", 148*49503Sbostic foff - minlen, (char *)bfr); 14930142Sbostic else 150*49503Sbostic printf("%s", bfr); 15130142Sbostic while ((ch = getch()) != EOF && ISSTR(ch)) 15230142Sbostic putchar((char)ch); 15330142Sbostic putchar('\n'); 1541105Sbill } 15530142Sbostic cnt = 0; 1561105Sbill } 15747678Smarc nextfile: ; 15830142Sbostic } while (*argv); 15947678Smarc exit(exitcode); 1601105Sbill } 1611105Sbill 16230142Sbostic /* 16330142Sbostic * getch -- 16430142Sbostic * get next character from wherever 16530142Sbostic */ 16630142Sbostic getch() 1671105Sbill { 16830142Sbostic ++foff; 16930142Sbostic if (head_len) { 17030142Sbostic if (hcnt < head_len) 17130142Sbostic return((int)hbfr[hcnt++]); 17230142Sbostic head_len = 0; 1731105Sbill } 17435980Sbostic if (read_len == -1 || read_len-- > 0) 17530142Sbostic return(getchar()); 17630142Sbostic return(EOF); 1771105Sbill } 178*49503Sbostic 179*49503Sbostic static void 180*49503Sbostic usage() 181*49503Sbostic { 182*49503Sbostic (void)fprintf(stderr, 183*49503Sbostic "usage: strings [-afo] [-n length] [file ... ]\n"); 184*49503Sbostic exit(1); 185*49503Sbostic } 186