1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1980, 1988, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33
34__FBSDID("$FreeBSD$");
35
36#ifndef lint
37static const char copyright[] =
38"@(#) Copyright (c) 1980, 1988, 1993\n\
39	The Regents of the University of California.  All rights reserved.\n";
40#endif
41
42#ifndef lint
43static const char sccsid[] = "@(#)what.c	8.1 (Berkeley) 6/6/93";
44#endif
45
46#include <err.h>
47#include <stdbool.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <unistd.h>
51
52static void usage(void);
53static bool search(bool, bool, FILE *);
54
55int
56main(int argc, char *argv[])
57{
58	const char *file;
59	FILE *in;
60	bool found, qflag, sflag;
61	int c;
62
63	qflag = sflag = false;
64
65	while ((c = getopt(argc, argv, "qs")) != -1) {
66		switch (c) {
67		case 'q':
68			qflag = true;
69			break;
70		case 's':
71			sflag = true;
72			break;
73		default:
74			usage();
75		}
76	}
77	argc -= optind;
78	argv += optind;
79
80	found = false;
81
82	if (argc == 0) {
83		if (search(sflag, qflag, stdin))
84			found = true;
85	} else {
86		while (argc--) {
87			file = *argv++;
88			in = fopen(file, "r");
89			if (in == NULL) {
90				if (!qflag)
91					warn("%s", file);
92				continue;
93			}
94			if (!qflag)
95				printf("%s:\n", file);
96			if (search(sflag, qflag, in))
97				found = true;
98			fclose(in);
99		}
100	}
101	exit(found ? 0 : 1);
102}
103
104static void
105usage(void)
106{
107	fprintf(stderr, "usage: what [-qs] [file ...]\n");
108	exit(1);
109}
110
111bool
112search(bool one, bool quiet, FILE *in)
113{
114	bool found;
115	int c;
116
117	found = false;
118
119	while ((c = getc(in)) != EOF) {
120loop:		if (c != '@')
121			continue;
122		if ((c = getc(in)) != '(')
123			goto loop;
124		if ((c = getc(in)) != '#')
125			goto loop;
126		if ((c = getc(in)) != ')')
127			goto loop;
128		if (!quiet)
129			putchar('\t');
130		while ((c = getc(in)) != EOF && c && c != '"' &&
131		    c != '>' && c != '\\' && c != '\n')
132			putchar(c);
133		putchar('\n');
134		found = true;
135		if (one)
136			break;
137	}
138	return (found);
139}
140