1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License ("CDDL"), version 1.0.
6  * You may use this file only in accordance with the terms of version
7  * 1.0 of the CDDL.
8  *
9  * A full copy of the text of the CDDL should have accompanied this
10  * source.  A copy of the CDDL is also available via the Internet at
11  * http://www.opensource.org/licenses/cddl1.txt
12  * See the License for the specific language governing permissions
13  * and limitations under the License.
14  *
15  * When distributing Covered Code, include this CDDL HEADER in each
16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17  * If applicable, add the following below this CDDL HEADER, with the
18  * fields enclosed by brackets "[]" replaced with your own identifying
19  * information: Portions Copyright [yyyy] [name of copyright owner]
20  *
21  * CDDL HEADER END
22  */
23 /* Copyright (c) 1988 AT&T */
24 /* All Rights Reserved */
25 /*
26  * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
27  * Use is subject to license terms.
28  */
29 /*
30  * Copyright 2006-2020 J. Schilling
31  *
32  * @(#)what.c	1.21 20/08/23 J. Schilling
33  */
34 #if defined(sun)
35 #pragma ident "@(#)what.c 1.21 20/08/23 J. Schilling"
36 #endif
37 /*
38  * @(#)what.c 1.11 06/12/12
39  */
40 
41 #if defined(sun)
42 #pragma ident	"@(#)what.c"
43 #pragma ident	"@(#)sccs:cmd/what.c"
44 #endif
45 #define		SCCS_MAIN			/* define global vars */
46 #include	<defines.h>
47 #include	<version.h>
48 #include	<i18n.h>
49 #include	<schily/sysexits.h>
50 
51 #define	MINUS	'-'
52 #define	MINUS_S	"-s"
53 #define	TRUE	1
54 #define	FALSE	0
55 
56 
57 static int found = FALSE;
58 static int silent = FALSE;
59 
60 static char	pattern[]  =  NOGETTEXT("@(#)");
61 
62 	int	main	__PR((int argc, char **argv));
63 static void	dowhat	__PR((FILE *iop));
64 static int	trypat	__PR((FILE *iop, char *pat));
65 
66 
67 int
main(argc,argv)68 main(argc, argv)
69 	int		argc;
70 	register char	**argv;
71 {
72 	register int i;
73 	register FILE *iop;
74 	int current_optind, c;
75 
76 	/*
77 	 * Set locale for all categories.
78 	 */
79 	setlocale(LC_ALL, NOGETTEXT(""));
80 
81 	sccs_setinsbase(INS_BASE);
82 
83 	/*
84 	 * Set directory to search for general l10n SCCS messages.
85 	 */
86 #ifdef	PROTOTYPES
87 	(void) bindtextdomain(NOGETTEXT("SUNW_SPRO_SCCS"),
88 	    NOGETTEXT(INS_BASE "/" SCCS_BIN_PRE "lib/locale/"));
89 #else
90 	(void) bindtextdomain(NOGETTEXT("SUNW_SPRO_SCCS"),
91 	    NOGETTEXT("/usr/ccs/lib/locale/"));
92 #endif
93 
94 	(void) textdomain(NOGETTEXT("SUNW_SPRO_SCCS"));
95 
96 	tzset();	/* Set up timezome related vars */
97 
98 #ifdef	SCHILY_BUILD
99 	save_args(argc, argv);
100 #endif
101 
102 	if (argc < 2)
103 		dowhat(stdin);
104 	else {
105 
106 		current_optind = 1;
107 		optind = 1;
108 		opterr = 0;
109 		i = 1;
110 		/*CONSTCOND*/
111 		while (1) {
112 			if (current_optind < optind) {
113 			    current_optind = optind;
114 			    argv[i] = 0;
115 			    if (optind > i+1) {
116 				argv[i+1] = NULL;
117 			    }
118 			}
119 			i = current_optind;
120 			c = getopt(argc, argv, "()-sV(version)");
121 
122 				/*
123 				 * This takes care of options given after
124 				 * file names.
125 				 */
126 			if (c == EOF) {
127 			    if (optind < argc) {
128 				/* if it's due to -- then break; */
129 				if (argv[i][0] == '-' &&
130 				    argv[i][1] == '-') {
131 					argv[i] = 0;
132 					break;
133 				}
134 				optind++;
135 				current_optind = optind;
136 				continue;
137 			    } else {
138 				break;
139 			    }
140 			}
141 			switch (c) {
142 			case 's' :
143 				silent = TRUE;
144 				break;
145 
146 			case 'V':		/* version */
147 				printf(gettext(
148 				"what %s-SCCS version %s %s (%s-%s-%s)\n"),
149 					PROVIDER,
150 					VERSION,
151 					VDATE,
152 					HOST_CPU, HOST_VENDOR, HOST_OS);
153 				exit(EX_OK);
154 
155 			default  :
156 				fatal(gettext(
157 					"Usage: what [ -s ] filename..."));
158 			}
159 		}
160 		for (i = 1; (i < argc); i++) {
161 			if (!argv[i]) {
162 				continue;
163 			}
164 			if ((iop = fopen(argv[i], NOGETTEXT("rb"))) == NULL)
165 				fprintf(stderr, gettext("can't open %s (26)\n"),
166 					argv[i]);
167 			else {
168 				printf("%s:\n", argv[i]);
169 				dowhat(iop);
170 			}
171 		}
172 	}
173 	return (!found);				/* shell return code */
174 }
175 
176 
177 static void
dowhat(iop)178 dowhat(iop)
179 register FILE *iop;
180 {
181 	register int c;
182 
183 	while ((c = getc(iop)) != EOF) {
184 		if (c == pattern[0])
185 			if (trypat(iop, &pattern[1]) && silent) break;
186 	}
187 	fclose(iop);
188 }
189 
190 
191 static int
trypat(iop,pat)192 trypat(iop, pat)
193 register FILE *iop;
194 register char *pat;
195 {
196 	register int c = EOF;
197 
198 	for (; *pat; pat++)
199 		if ((c = getc(iop)) != *pat)
200 			break;
201 	if (!*pat) {
202 		found = TRUE;
203 		putchar('\t');
204 		while ((c = getc(iop)) != EOF && c &&
205 		    !any(c, NOGETTEXT("\"\\>\n")))
206 			putchar(c);
207 		putchar('\n');
208 		if (silent)
209 			return (TRUE);
210 	} else if (c != EOF)
211 		ungetc(c, iop);
212 	return (FALSE);
213 }
214