/*	Copyright (c) 1984, 1986, 1987, 1988 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

#ident	"$Header: strings.c 1.1 90/05/01 $"

/* Copyright (c) 1979 Regents of the University of California */

/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 */

#include <stdio.h>
#include <ctype.h>
#include <filehdr.h>
#include <scnhdr.h>
#include <ldfcn.h>

# define NOTOUT		0

long	ftell();
#define dirt(c) (!isascii(c) || !isprint(c))
/*
 * Strings - extract strings from an object file for whatever
 *
 * Bill Joy UCB 
 * April 22, 1978
 *
 * The algorithm is to look for sequences of "non-junk" characters
 * The variable "minlen" is the minimum length string printed.
 * This helps get rid of garbage.
 * Default minimum string length is 4 characters.
 *
 */

/*
 * Modified 30-Apr-90 for COFF objects.  Seqent Computer Systems, Inc.
 */


char	*infile = "Standard input";
int	oflg;
int	asdata;
long	offset;
int	minlength = 4;

FILHDR	filehead;
SCNHDR	secthdr;

main(argc, argv)
	int argc;
	char *argv[];
{
	argc--, argv++;
	while (argc > 0 && argv[0][0] == '-') {
		register int i;
		if (argv[0][1] == 0)
			asdata++;
		else
			for (i = 1; argv[0][i] != 0; i++)
				switch (argv[0][i]) {

				case 'o':
					oflg++;
					break;

				case 'a':
					asdata++;
					break;

				default:
					if (!isdigit(argv[0][i])) {
						fprintf(stderr, "Usage: strings [ - ] [ -o ] [ -# ] [ file ... ]\n");
						exit(1);
					}
					minlength = argv[0][i] - '0';
					for (i++; isdigit(argv[0][i]); i++)
						minlength = minlength * 10 + argv[0][i] - '0';
					i--;
					break;
				}
		argc--, argv++;
	}

	do {
		if (argc > 0) {
			if (freopen(argv[0], "r", stdin) == NULL) {
				perror(argv[0]);
				exit(1);
			}
			infile = argv[0];
			argc--, argv++;
		}
		if (!asdata) {
			if (fread(&filehead, FILHSZ, 1, stdin) != 1) {
				fseek(stdin, (long) 0, 0);
				find((long) 100000000L);
				continue;
			}
			if ((filehead.f_magic == I386MAGIC) ||
			    (filehead.f_magic) == SVI386MAGIC) {
				if(find_text()) {
				    fseek(stdin, (long) secthdr.s_scnptr, 0);
				    find(secthdr.s_size);
				} else {
				    fseek(stdin, (long) 0, 0);
				    find((long) 100000000L);
				}
			} else {
				fseek(stdin, (long) 0, 0);
				find((long) 100000000L);
			}
		} else {
			fseek(stdin, (long) 0, 0);
			find((long) 100000000L);
			continue;
		}
	} while (argc > 0);
}

find(cnt)
	long cnt;
{
	static char buf[BUFSIZ];
	register int c, cc;

	cc = 0;
	for (c = !EOF; (cnt > 0) && (c != EOF); cnt--) {
		c = getc(stdin);
		if (dirt(c)) {
			if (cc >= minlength) {
				if (oflg)
					printf("%7ld ", ftell(stdin) - cc - 1);
				buf[cc] = '\0';
				puts(buf);
			}
			cc = 0;
		} else {
			if (cc < (BUFSIZ - 2))
				buf[cc] = c;
			++cc;
		}
	}
}

find_text()
{
	int numsects, i;

	numsects = filehead.f_nscns;

	if (fseek(stdin, (long) FILHSZ + filehead.f_opthdr, 0) != 0)
		return(0);

	for (i=0; (i < numsects) && 
	          (fread(&secthdr, SCNHSZ, 1, stdin) == 1);
		i++) {
		if (strcmp(secthdr.s_name, ".data") == 0)
			return(1);
	}
	return(0);
}
