121577Sdist /* 221577Sdist * Copyright (c) 1980 Regents of the University of California. 321577Sdist * All rights reserved. The Berkeley software License Agreement 421577Sdist * specifies the terms and conditions for redistribution. 521577Sdist */ 621577Sdist 717267Ssam #ifndef lint 821577Sdist char copyright[] = 921577Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1021577Sdist All rights reserved.\n"; 1121577Sdist #endif not lint 1217267Ssam 1321577Sdist #ifndef lint 14*30142Sbostic static char sccsid[] = "@(#)strings.c 5.2 (Berkeley) 11/24/86"; 1521577Sdist #endif not lint 1621577Sdist 17*30142Sbostic #include <sys/types.h> 18*30142Sbostic #include <sys/file.h> 19*30142Sbostic #include <a.out.h> 201105Sbill #include <stdio.h> 211105Sbill #include <ctype.h> 221105Sbill 23*30142Sbostic #define DEF_LEN 4 /* default minimum string length */ 24*30142Sbostic #define EOS (char)NULL /* end of string */ 25*30142Sbostic #define ERR -1 /* general error */ 26*30142Sbostic #define ERREXIT 1 /* error exit */ 27*30142Sbostic #define NO 0 /* false/no */ 28*30142Sbostic #define OK 0 /* ok exit */ 29*30142Sbostic #define YES 1 /* true/yes */ 301105Sbill 31*30142Sbostic #define ISSTR(ch) (isascii(ch) && (isprint(ch) || ch == '\t')) 321105Sbill 33*30142Sbostic typedef struct exec EXEC; /* struct exec cast */ 341105Sbill 35*30142Sbostic static long foff; /* offset in the file */ 36*30142Sbostic static int hcnt, /* head count */ 37*30142Sbostic head_len, /* length of header */ 38*30142Sbostic read_len; /* length to read */ 39*30142Sbostic static u_char hbfr[sizeof(EXEC)]; /* buffer for struct exec */ 401105Sbill 41*30142Sbostic main(argc,argv) 42*30142Sbostic int argc; 43*30142Sbostic char **argv; 441105Sbill { 45*30142Sbostic register int ch, /* character */ 46*30142Sbostic cnt; /* general counter */ 47*30142Sbostic register u_char *C; /* bfr pointer */ 48*30142Sbostic EXEC *head; /* exec header pointer */ 49*30142Sbostic int minlen = DEF_LEN; /* minimum string length */ 50*30142Sbostic short asdata = NO, /* look in everything */ 51*30142Sbostic oflg; /* print octal location */ 52*30142Sbostic u_char *bfr; /* collection buffer */ 53*30142Sbostic char *file, /* file name for error */ 54*30142Sbostic *malloc(); 551105Sbill 56*30142Sbostic /* 57*30142Sbostic * for backward compatibility, allow '-' to specify 'a' flag; no 58*30142Sbostic * longer documented in the man page or usage string. 59*30142Sbostic */ 60*30142Sbostic for (++argv;*argv && **argv == '-';++argv) { 61*30142Sbostic for (cnt = 1;(*argv)[cnt];++cnt) 62*30142Sbostic switch ((*argv)[cnt]) { 63*30142Sbostic case 'a': 64*30142Sbostic asdata = YES; 65*30142Sbostic break; 66*30142Sbostic case 'o': 67*30142Sbostic oflg = YES; 68*30142Sbostic break; 69*30142Sbostic default: /* getopt message compatible */ 70*30142Sbostic if (!isdigit((*argv)[cnt])) { 71*30142Sbostic fprintf(stderr,"strings: illegal option -- %c\nusage: strings [-ao] [-#] [file ... ]\n",(*argv)[cnt]); 72*30142Sbostic exit(ERREXIT); 73*30142Sbostic } 74*30142Sbostic minlen = atoi(*argv + 1); 75*30142Sbostic break; 761105Sbill } 77*30142Sbostic if (cnt == 1) 78*30142Sbostic asdata = YES; 791105Sbill } 80*30142Sbostic 81*30142Sbostic if (!(bfr = (u_char *)malloc((u_int)minlen))) { 82*30142Sbostic fputs("strings: unable to allocate space.\n",stderr); 83*30142Sbostic exit(ERREXIT); 84*30142Sbostic } 85*30142Sbostic bfr[minlen] = EOS; 86*30142Sbostic file = "stdin"; 871105Sbill do { 88*30142Sbostic if (*argv) { 89*30142Sbostic if (!freopen(*argv,"r",stdin)) { 90*30142Sbostic perror(*argv); 91*30142Sbostic exit(ERREXIT); 921105Sbill } 93*30142Sbostic file = *argv++; 941105Sbill } 95*30142Sbostic foff = 0; 96*30142Sbostic read_len = ERR; 97*30142Sbostic if (asdata) 98*30142Sbostic head_len = 0; 99*30142Sbostic else { 100*30142Sbostic head = (EXEC *)hbfr; 101*30142Sbostic if ((head_len = read(fileno(stdin),(char *)head,sizeof(EXEC))) == ERR) { 102*30142Sbostic perror(file); 103*30142Sbostic exit(ERREXIT); 104*30142Sbostic } 105*30142Sbostic if (head_len == sizeof(EXEC) && !N_BADMAG(*head)) { 106*30142Sbostic foff = N_TXTOFF(*head) + head->a_text; 107*30142Sbostic if (fseek(stdin,foff,L_SET) == ERR) { 108*30142Sbostic perror(file); 109*30142Sbostic exit(ERREXIT); 110*30142Sbostic } 111*30142Sbostic read_len = head->a_data; 112*30142Sbostic head_len = 0; 113*30142Sbostic } 114*30142Sbostic else 115*30142Sbostic hcnt = 0; 1161105Sbill } 117*30142Sbostic for (cnt = 0;(ch = getch()) != EOF;) { 118*30142Sbostic if (ISSTR(ch)) { 119*30142Sbostic if (!cnt) 120*30142Sbostic C = bfr; 121*30142Sbostic *C++ = ch; 122*30142Sbostic if (++cnt < minlen) 123*30142Sbostic continue; 1241105Sbill if (oflg) 125*30142Sbostic printf("%07lo %s",foff - minlen,bfr); 126*30142Sbostic else 127*30142Sbostic fputs((char *)bfr,stdout); 128*30142Sbostic while ((ch = getch()) != EOF && ISSTR(ch)) 129*30142Sbostic putchar((char)ch); 130*30142Sbostic putchar('\n'); 1311105Sbill } 132*30142Sbostic cnt = 0; 1331105Sbill } 134*30142Sbostic } while (*argv); 135*30142Sbostic exit(OK); 1361105Sbill } 1371105Sbill 138*30142Sbostic /* 139*30142Sbostic * getch -- 140*30142Sbostic * get next character from wherever 141*30142Sbostic */ 142*30142Sbostic static 143*30142Sbostic getch() 1441105Sbill { 145*30142Sbostic ++foff; 146*30142Sbostic if (head_len) { 147*30142Sbostic if (hcnt < head_len) 148*30142Sbostic return((int)hbfr[hcnt++]); 149*30142Sbostic head_len = 0; 1501105Sbill } 151*30142Sbostic if (read_len == ERR || read_len-- > 0) 152*30142Sbostic return(getchar()); 153*30142Sbostic return(EOF); 1541105Sbill } 155