xref: /titanic_53/usr/src/cmd/svr4pkg/libinst/scriptvfy.l (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland 
28*5c51f124SMoriah Waterland /*
29*5c51f124SMoriah Waterland  * The purpose of this lex specification is to estimate the
30*5c51f124SMoriah Waterland  * correctness of the various scripts that accompany packages. It
31*5c51f124SMoriah Waterland  * is not flawless, but it is a better review than that of prior
32*5c51f124SMoriah Waterland  * package validators. It looks for indications of interaction,
33*5c51f124SMoriah Waterland  * root calls and attempts to modify locked files.
34*5c51f124SMoriah Waterland  */
35*5c51f124SMoriah Waterland %e 1500
36*5c51f124SMoriah Waterland %p 3500
37*5c51f124SMoriah Waterland %s WHROOT
38*5c51f124SMoriah Waterland %{
39*5c51f124SMoriah Waterland #undef	input
40*5c51f124SMoriah Waterland #undef	unput
41*5c51f124SMoriah Waterland FILE *scr_fp;
42*5c51f124SMoriah Waterland #define	input()		(((yytchar=yysptr>yysbuf?U(*--yysptr):getc(scr_fp))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
43*5c51f124SMoriah Waterland #define	unput(p)	ungetc(p, scr_fp)
44*5c51f124SMoriah Waterland 
45*5c51f124SMoriah Waterland #define	INTERACT_D	0x00000001	/* definitely */
46*5c51f124SMoriah Waterland #define	ROOT_D		0x00000002
47*5c51f124SMoriah Waterland #define	LOCKED_D	0x00000004
48*5c51f124SMoriah Waterland #define	INTERACT_M	0x00010000	/* might be true, or we ... */
49*5c51f124SMoriah Waterland #define	ROOT_M		0x00020000	/* ... might be reading it wrong. */
50*5c51f124SMoriah Waterland #define	LOCKED_M	0x00040000
51*5c51f124SMoriah Waterland #define	WPARM1_M	0x00080000	/* attempt to write to $1 */
52*5c51f124SMoriah Waterland #define	USEPARM1_M	0x00100000	/* other attempt to use $1 */
53*5c51f124SMoriah Waterland #define	ODDPARM_M	0x00200000	/* use of some other parameter */
54*5c51f124SMoriah Waterland #define	PKGDB_M		0x00400000	/* read access to DB */
55*5c51f124SMoriah Waterland #define	INITVAL		0x40000000
56*5c51f124SMoriah Waterland 
57*5c51f124SMoriah Waterland /* Abbreviations */
58*5c51f124SMoriah Waterland #define	INTERACT	(INTERACT_D | INTERACT_M)
59*5c51f124SMoriah Waterland #define	ROOT		(ROOT_D | ROOT_M)
60*5c51f124SMoriah Waterland #define	LOCKED		(LOCKED_D | LOCKED_M)
61*5c51f124SMoriah Waterland #define	HASPARM		(WPARM1_M | USEPARM1_M | ODDPARM_M)
62*5c51f124SMoriah Waterland 
63*5c51f124SMoriah Waterland /* Things the preinstall and preremove scripts can't do. */
64*5c51f124SMoriah Waterland #define	PRE_MASK	(INTERACT | LOCKED | PKGDB_M | HASPARM)
65*5c51f124SMoriah Waterland /*
66*5c51f124SMoriah Waterland  * Things the class action script can't do. Don't get the impression that
67*5c51f124SMoriah Waterland  * this means the class action script can be interactive; but, it can
68*5c51f124SMoriah Waterland  * legitimately read stdin (which is what INTERACT tests for).
69*5c51f124SMoriah Waterland  */
70*5c51f124SMoriah Waterland #define	CAS_MASK	(LOCKED | PKGDB_M | WPARM1_M | ODDPARM_M)
71*5c51f124SMoriah Waterland /* Things the postinstall and postremove scripts can't do. */
72*5c51f124SMoriah Waterland #define	POST_MASK	(INTERACT | HASPARM)
73*5c51f124SMoriah Waterland /* Things the request script can't do. */
74*5c51f124SMoriah Waterland #define	REQ_MASK	(ROOT | ODDPARM_M)
75*5c51f124SMoriah Waterland /* Things the checkinstall script can't do. */
76*5c51f124SMoriah Waterland #define	CHK_MASK	(INTERACT | ROOT | ODDPARM_M)
77*5c51f124SMoriah Waterland 
78*5c51f124SMoriah Waterland /* Nothing definite - not worth returning an error */
79*5c51f124SMoriah Waterland #define	MAYBE_ONLY	~(INTERACT_D | ROOT_D | LOCKED_D)
80*5c51f124SMoriah Waterland 
81*5c51f124SMoriah Waterland #define	WRN_INST_F	"WARNING: script <%s> uses installf but no " \
82*5c51f124SMoriah Waterland 			    "installf -f was detected."
83*5c51f124SMoriah Waterland #define	WRN_REM_F	"WARNING: script <%s> uses removef but no " \
84*5c51f124SMoriah Waterland 			    "removef -f was detected."
85*5c51f124SMoriah Waterland #define	WRN_INTERACT	"WARNING: script <%s> may require " \
86*5c51f124SMoriah Waterland 			    "user interaction at line <%d>."
87*5c51f124SMoriah Waterland #define	WRN_LOCKED	"WARNING: script <%s> may seek access to the " \
88*5c51f124SMoriah Waterland 			    "transitional package database at line <%d>. " \
89*5c51f124SMoriah Waterland 			    "This is safest in the postinstall or " \
90*5c51f124SMoriah Waterland 			    "postremove script."
91*5c51f124SMoriah Waterland #define	WRN_ROOT	"WARNING: script <%s> may not have permission " \
92*5c51f124SMoriah Waterland 			    "to execute line <%d>."
93*5c51f124SMoriah Waterland #define	WRN_FORM_ARG	"WARNING: not sure where script <%s> gets the "\
94*5c51f124SMoriah Waterland 			    "parameter at line <%d>."
95*5c51f124SMoriah Waterland #define	WRN_FORM_USE	"WARNING: script <%s> questionable usage of "\
96*5c51f124SMoriah Waterland 			    "parameter at line <%d>."
97*5c51f124SMoriah Waterland #define	WRN_TRANSDB	"WARNING: script <%s> questionable read " \
98*5c51f124SMoriah Waterland 			    "of package database at line <%d>. An " \
99*5c51f124SMoriah Waterland 			    "intermediate buffer may be appropriate."
100*5c51f124SMoriah Waterland #define	WRN_SPACEACC	"WARNING: script <%s> updates the package database " \
101*5c51f124SMoriah Waterland 			    "but provides no space file to account for " \
102*5c51f124SMoriah Waterland 			    "the additional package object."
103*5c51f124SMoriah Waterland #define	ERR_INTERACT	"ERROR: script <%s> requires user " \
104*5c51f124SMoriah Waterland 			    "interaction at line <%d>."
105*5c51f124SMoriah Waterland #define	ERR_LOCKED	"ERROR: script <%s> attempts to modify locked " \
106*5c51f124SMoriah Waterland 			    "package database at line <%d>."
107*5c51f124SMoriah Waterland #define	ERR_ROOT	"ERROR: script <%s> requires root permission at " \
108*5c51f124SMoriah Waterland 			    "line <%d>."
109*5c51f124SMoriah Waterland #define	ERR_FOPEN	"ERROR: Cannot evaluate script <%s>, errno=%d."
110*5c51f124SMoriah Waterland #define	ERR_ARGS	"ERROR: scripteval() - no script provided for " \
111*5c51f124SMoriah Waterland 			    "evaluation."
112*5c51f124SMoriah Waterland extern int errno;
113*5c51f124SMoriah Waterland 
114*5c51f124SMoriah Waterland static int line_no;	/* current line number */
115*5c51f124SMoriah Waterland int pipe_release = 0;	/* loop level for release of pipe */
116*5c51f124SMoriah Waterland int loop_depth = 0;	/* current number of nested loops */
117*5c51f124SMoriah Waterland int case_depth = 0;	/* same for case ... */
118*5c51f124SMoriah Waterland int if_depth = 0;	/* ... and if statements */
119*5c51f124SMoriah Waterland int cur_level = 0;	/* current number of nested anything */
120*5c51f124SMoriah Waterland int braces = 0;		/* depth into a function */
121*5c51f124SMoriah Waterland 
122*5c51f124SMoriah Waterland int lock_level = 0;
123*5c51f124SMoriah Waterland int root_level = 0;
124*5c51f124SMoriah Waterland 
125*5c51f124SMoriah Waterland struct statstrct {
126*5c51f124SMoriah Waterland 	unsigned int in_function:1;
127*5c51f124SMoriah Waterland 	unsigned int in_pipe:1;
128*5c51f124SMoriah Waterland 	unsigned int in_loop:1;
129*5c51f124SMoriah Waterland 	unsigned int in_case:1;
130*5c51f124SMoriah Waterland 	unsigned int in_if:1;
131*5c51f124SMoriah Waterland 	unsigned int in_awk:1;
132*5c51f124SMoriah Waterland 	unsigned int allow_int:1;	/* Allow an interactive function. */
133*5c51f124SMoriah Waterland 	unsigned int pkg_rtn_done:1;
134*5c51f124SMoriah Waterland 	unsigned int pkgchk_f:1;
135*5c51f124SMoriah Waterland 	unsigned int instf:1;
136*5c51f124SMoriah Waterland 	unsigned int instf_f:1;
137*5c51f124SMoriah Waterland 	unsigned int remf:1;
138*5c51f124SMoriah Waterland 	unsigned int remf_f:1;
139*5c51f124SMoriah Waterland 	unsigned int nospacefile:1;
140*5c51f124SMoriah Waterland 	unsigned int needspacefile:1;
141*5c51f124SMoriah Waterland } status = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
142*5c51f124SMoriah Waterland 
143*5c51f124SMoriah Waterland %}
144*5c51f124SMoriah Waterland %%
145*5c51f124SMoriah Waterland %{
146*5c51f124SMoriah Waterland /*
147*5c51f124SMoriah Waterland  * Validate a few OK patterns that look like bad patterns. These include:
148*5c51f124SMoriah Waterland  *	1. comments
149*5c51f124SMoriah Waterland  *	2. quoted strings
150*5c51f124SMoriah Waterland  *	3. writes to $1 (request script)
151*5c51f124SMoriah Waterland  *	4. reads from $1 (CAS)
152*5c51f124SMoriah Waterland  *	5. writes to /dev/null
153*5c51f124SMoriah Waterland  */
154*5c51f124SMoriah Waterland %}
155*5c51f124SMoriah Waterland #.*$ 	return INITVAL;
156*5c51f124SMoriah Waterland 
157*5c51f124SMoriah Waterland \`	unput(' ');	/* No executable matching */
158*5c51f124SMoriah Waterland 
159*5c51f124SMoriah Waterland %{
160*5c51f124SMoriah Waterland /* Anybody can write to /dev/null and anybody can write to /tmp. */
161*5c51f124SMoriah Waterland %}
162*5c51f124SMoriah Waterland \>[ \t]*"/dev/null"	return INITVAL;
163*5c51f124SMoriah Waterland \>[ \t]*"/tmp"		return INITVAL;
164*5c51f124SMoriah Waterland 
165*5c51f124SMoriah Waterland %{
166*5c51f124SMoriah Waterland /* If it's escaped, the next entry may as well be a space. */
167*5c51f124SMoriah Waterland %}
168*5c51f124SMoriah Waterland \\	{
169*5c51f124SMoriah Waterland 	char ch;
170*5c51f124SMoriah Waterland 
171*5c51f124SMoriah Waterland 	if ((ch = input()) == '\n')
172*5c51f124SMoriah Waterland 		line_no++;
173*5c51f124SMoriah Waterland 
174*5c51f124SMoriah Waterland 	unput(' ');
175*5c51f124SMoriah Waterland }
176*5c51f124SMoriah Waterland 
177*5c51f124SMoriah Waterland %{
178*5c51f124SMoriah Waterland /* In the quotes is OK. */
179*5c51f124SMoriah Waterland %}
180*5c51f124SMoriah Waterland \"	{
181*5c51f124SMoriah Waterland 	char ch;
182*5c51f124SMoriah Waterland 	while ((ch = input()) != '\"') {
183*5c51f124SMoriah Waterland 		if (ch == '\\') {
184*5c51f124SMoriah Waterland 			input();	/* Read this into the bit bucket. */
185*5c51f124SMoriah Waterland 			continue;
186*5c51f124SMoriah Waterland 		}
187*5c51f124SMoriah Waterland 		if (ch == '\n')
188*5c51f124SMoriah Waterland 			line_no++;
189*5c51f124SMoriah Waterland 		else if (ch == '\0')
190*5c51f124SMoriah Waterland 			return (0);	/* EOF */
191*5c51f124SMoriah Waterland 	}
192*5c51f124SMoriah Waterland }
193*5c51f124SMoriah Waterland 
194*5c51f124SMoriah Waterland %{
195*5c51f124SMoriah Waterland /* In the single quotes is OK if they aren't associated with an awk script. */
196*5c51f124SMoriah Waterland %}
197*5c51f124SMoriah Waterland \'	{
198*5c51f124SMoriah Waterland 	char ch;
199*5c51f124SMoriah Waterland 
200*5c51f124SMoriah Waterland 	if (status.in_awk != 0)
201*5c51f124SMoriah Waterland 		REJECT;;
202*5c51f124SMoriah Waterland 
203*5c51f124SMoriah Waterland 	while ((ch = input()) != '\'') {
204*5c51f124SMoriah Waterland 		if (ch == '\\') {
205*5c51f124SMoriah Waterland 			input();	/* Read this into the bit bucket. */
206*5c51f124SMoriah Waterland 			continue;
207*5c51f124SMoriah Waterland 		}
208*5c51f124SMoriah Waterland 		if (ch == '\n')
209*5c51f124SMoriah Waterland 			line_no++;
210*5c51f124SMoriah Waterland 		else if (ch == '\0')
211*5c51f124SMoriah Waterland 			return (0);	/* EOF */
212*5c51f124SMoriah Waterland 	}
213*5c51f124SMoriah Waterland }
214*5c51f124SMoriah Waterland 
215*5c51f124SMoriah Waterland %{
216*5c51f124SMoriah Waterland /*
217*5c51f124SMoriah Waterland  * Check for use of parameters passed to the script.
218*5c51f124SMoriah Waterland  *	1. writes to $1 as though it were a file
219*5c51f124SMoriah Waterland  *	2. use of $1 in any capacity
220*5c51f124SMoriah Waterland  *	3. use of other parameters
221*5c51f124SMoriah Waterland  * Within a function or an awk script, these parameters aren't
222*5c51f124SMoriah Waterland  * the one's of interest.
223*5c51f124SMoriah Waterland  */
224*5c51f124SMoriah Waterland %}
225*5c51f124SMoriah Waterland \>[\t ]*\$1/[\t\n ]	{
226*5c51f124SMoriah Waterland 	if (status.in_function == 0 && status.in_awk == 0)
227*5c51f124SMoriah Waterland 		return (WPARM1_M);
228*5c51f124SMoriah Waterland }
229*5c51f124SMoriah Waterland 
230*5c51f124SMoriah Waterland ^$1/[\t\n ]	|
231*5c51f124SMoriah Waterland [\t ]$1/[\t\n ]	{
232*5c51f124SMoriah Waterland 	if (status.in_function == 0 && status.in_awk == 0)
233*5c51f124SMoriah Waterland 		return (USEPARM1_M);
234*5c51f124SMoriah Waterland }
235*5c51f124SMoriah Waterland 
236*5c51f124SMoriah Waterland \$[2-9]	|
237*5c51f124SMoriah Waterland \$[0-9][0-9]+ {
238*5c51f124SMoriah Waterland 	if (status.in_function == 0 && status.in_awk == 0)
239*5c51f124SMoriah Waterland 		return (ODDPARM_M);
240*5c51f124SMoriah Waterland }
241*5c51f124SMoriah Waterland 
242*5c51f124SMoriah Waterland %{
243*5c51f124SMoriah Waterland /*
244*5c51f124SMoriah Waterland  * Detect shell function.
245*5c51f124SMoriah Waterland  */
246*5c51f124SMoriah Waterland %}
247*5c51f124SMoriah Waterland "()"[ \t]*\n[ \t]*/\{	{ status.in_function = 1; line_no++; }
248*5c51f124SMoriah Waterland "()"[ ]*/\{	status.in_function = 1;
249*5c51f124SMoriah Waterland 
250*5c51f124SMoriah Waterland "{" {
251*5c51f124SMoriah Waterland 	if (status.in_function == 1)
252*5c51f124SMoriah Waterland 		braces++;
253*5c51f124SMoriah Waterland }
254*5c51f124SMoriah Waterland 
255*5c51f124SMoriah Waterland "}" {
256*5c51f124SMoriah Waterland 	if (status.in_function == 1) {
257*5c51f124SMoriah Waterland 		braces--;
258*5c51f124SMoriah Waterland 		if (braces == 0)
259*5c51f124SMoriah Waterland 			status.in_function = 0;
260*5c51f124SMoriah Waterland 	}
261*5c51f124SMoriah Waterland }
262*5c51f124SMoriah Waterland 
263*5c51f124SMoriah Waterland %{
264*5c51f124SMoriah Waterland /*
265*5c51f124SMoriah Waterland  * Detect for or while loop.
266*5c51f124SMoriah Waterland  */
267*5c51f124SMoriah Waterland %}
268*5c51f124SMoriah Waterland ^for/[\t\n ]		|
269*5c51f124SMoriah Waterland [\t ]for/[\t\n ]	|
270*5c51f124SMoriah Waterland ^while/[\t\n ]		|
271*5c51f124SMoriah Waterland [\t ]while/[\t\n ] {
272*5c51f124SMoriah Waterland 	status.in_loop = 1;
273*5c51f124SMoriah Waterland 	loop_depth++;
274*5c51f124SMoriah Waterland 	cur_level++;
275*5c51f124SMoriah Waterland 	REJECT;		/* What's in the argument is important too. */
276*5c51f124SMoriah Waterland }
277*5c51f124SMoriah Waterland 
278*5c51f124SMoriah Waterland ^done/[\t\n ] 	|
279*5c51f124SMoriah Waterland [\t ]done/[\t\n ]  {
280*5c51f124SMoriah Waterland 	if (status.in_loop == 1)
281*5c51f124SMoriah Waterland 		loop_depth--;
282*5c51f124SMoriah Waterland 		cur_level--;
283*5c51f124SMoriah Waterland 		if (loop_depth == 0)
284*5c51f124SMoriah Waterland 			status.in_loop = 0;
285*5c51f124SMoriah Waterland }
286*5c51f124SMoriah Waterland 
287*5c51f124SMoriah Waterland %{
288*5c51f124SMoriah Waterland /*
289*5c51f124SMoriah Waterland  * Detect case.
290*5c51f124SMoriah Waterland  */
291*5c51f124SMoriah Waterland %}
292*5c51f124SMoriah Waterland ^case/[\t\n ]	|
293*5c51f124SMoriah Waterland [\t ]case/[\t\n ] {
294*5c51f124SMoriah Waterland 	status.in_case = 1;
295*5c51f124SMoriah Waterland 	case_depth++;
296*5c51f124SMoriah Waterland 	cur_level++;
297*5c51f124SMoriah Waterland 	REJECT;		/* What's in the argument is important too. */
298*5c51f124SMoriah Waterland }
299*5c51f124SMoriah Waterland 
300*5c51f124SMoriah Waterland ^esac/[\t\n ] 	|
301*5c51f124SMoriah Waterland [\t ]esac/[\t\n ] {
302*5c51f124SMoriah Waterland 	if (status.in_case == 1)
303*5c51f124SMoriah Waterland 		case_depth--;
304*5c51f124SMoriah Waterland 		cur_level--;
305*5c51f124SMoriah Waterland 		if (case_depth == 0)
306*5c51f124SMoriah Waterland 			status.in_case = 0;
307*5c51f124SMoriah Waterland }
308*5c51f124SMoriah Waterland 
309*5c51f124SMoriah Waterland %{
310*5c51f124SMoriah Waterland /*
311*5c51f124SMoriah Waterland  * Detect if.
312*5c51f124SMoriah Waterland  */
313*5c51f124SMoriah Waterland %}
314*5c51f124SMoriah Waterland ^if" "*"["	|
315*5c51f124SMoriah Waterland [\t ]if" "*"[" {
316*5c51f124SMoriah Waterland 	status.in_if = 1;
317*5c51f124SMoriah Waterland 	if_depth++;
318*5c51f124SMoriah Waterland 	cur_level++;
319*5c51f124SMoriah Waterland 	REJECT;		/* What's in the argument is important too. */
320*5c51f124SMoriah Waterland }
321*5c51f124SMoriah Waterland 
322*5c51f124SMoriah Waterland ^fi/[\t\n ]	|
323*5c51f124SMoriah Waterland [\t ]fi/[\t\n ]  {
324*5c51f124SMoriah Waterland 	if (status.in_if == 1)
325*5c51f124SMoriah Waterland 		if_depth--;
326*5c51f124SMoriah Waterland 		cur_level--;
327*5c51f124SMoriah Waterland 		if (if_depth == 0)
328*5c51f124SMoriah Waterland 			status.in_if = 0;
329*5c51f124SMoriah Waterland }
330*5c51f124SMoriah Waterland 
331*5c51f124SMoriah Waterland %{
332*5c51f124SMoriah Waterland /*
333*5c51f124SMoriah Waterland  * Detect awk or nawk function. If the function is enclosed in "`"s
334*5c51f124SMoriah Waterland  * the entire line will be grabbed., so we check for that possibility.
335*5c51f124SMoriah Waterland  */
336*5c51f124SMoriah Waterland %}
337*5c51f124SMoriah Waterland ^n?awk[^\n^']*\' 	|
338*5c51f124SMoriah Waterland [\t \\\(\/]n?awk[^\n^']*\'	status.in_awk = 1;
339*5c51f124SMoriah Waterland 
340*5c51f124SMoriah Waterland 
341*5c51f124SMoriah Waterland \' {
342*5c51f124SMoriah Waterland 	if (status.in_awk == 1)
343*5c51f124SMoriah Waterland 		status.in_awk = 0;
344*5c51f124SMoriah Waterland }
345*5c51f124SMoriah Waterland 
346*5c51f124SMoriah Waterland %{
347*5c51f124SMoriah Waterland /* Detect pipe target. */
348*5c51f124SMoriah Waterland %}
349*5c51f124SMoriah Waterland [\$A-Za-z]	{
350*5c51f124SMoriah Waterland 	if (status.in_pipe == 1 && pipe_release == cur_level)
351*5c51f124SMoriah Waterland 	{
352*5c51f124SMoriah Waterland 		status.in_pipe = 0;	/* target located */
353*5c51f124SMoriah Waterland 		pipe_release = 0;
354*5c51f124SMoriah Waterland 		status.allow_int = 1;	/* this isn't really interactive. */
355*5c51f124SMoriah Waterland 		REJECT;	/* put it back */
356*5c51f124SMoriah Waterland 	}
357*5c51f124SMoriah Waterland }
358*5c51f124SMoriah Waterland 
359*5c51f124SMoriah Waterland %{
360*5c51f124SMoriah Waterland /* If it's a pipe, note that and continue. */
361*5c51f124SMoriah Waterland %}
362*5c51f124SMoriah Waterland "||"		|
363*5c51f124SMoriah Waterland "|"		{
364*5c51f124SMoriah Waterland 	if (status.in_pipe == 0) {
365*5c51f124SMoriah Waterland 		status.in_pipe = 1;
366*5c51f124SMoriah Waterland 		pipe_release = cur_level;
367*5c51f124SMoriah Waterland 	}
368*5c51f124SMoriah Waterland }
369*5c51f124SMoriah Waterland 
370*5c51f124SMoriah Waterland %{
371*5c51f124SMoriah Waterland /*
372*5c51f124SMoriah Waterland  * Test input for admin-type telltale interactive functions. Definite's
373*5c51f124SMoriah Waterland  * first, maybe's next.
374*5c51f124SMoriah Waterland  */
375*5c51f124SMoriah Waterland %}
376*5c51f124SMoriah Waterland ^ckdate/[\t\n ]		|
377*5c51f124SMoriah Waterland [\t \/]ckdate/[\t\n ]	|
378*5c51f124SMoriah Waterland ^ckint/[\t\n ]		|
379*5c51f124SMoriah Waterland [\t \/]ckint/[\t\n ]	|
380*5c51f124SMoriah Waterland ^ckrange/[\t\n ]	|
381*5c51f124SMoriah Waterland [\t \/]ckrange/[\t\n ]	|
382*5c51f124SMoriah Waterland ^cktime/[\t\n ]		|
383*5c51f124SMoriah Waterland [\t \/]cktime/[\t\n ]	|
384*5c51f124SMoriah Waterland ^ckyorn/[\t\n ]		|
385*5c51f124SMoriah Waterland [\t \/]ckyorn/[\t\n ]	|
386*5c51f124SMoriah Waterland ^ckgid/[\t\n ]		|
387*5c51f124SMoriah Waterland [\t \/]ckgid/[\t\n ]	|
388*5c51f124SMoriah Waterland ^ckpath/[\t\n ]		|
389*5c51f124SMoriah Waterland [\t \/]ckpath/[\t\n ]	|
390*5c51f124SMoriah Waterland ^ckstr/[\t\n ]		|
391*5c51f124SMoriah Waterland [\t \/]ckstr/[\t\n ]	|
392*5c51f124SMoriah Waterland ^ckuid/[\t\n ]		|
393*5c51f124SMoriah Waterland [\t \/]ckuid/[\t\n ]		{
394*5c51f124SMoriah Waterland 	if (status.in_pipe == 1 || status.allow_int == 1)
395*5c51f124SMoriah Waterland 		return (INITVAL);
396*5c51f124SMoriah Waterland 	else
397*5c51f124SMoriah Waterland 		return (INTERACT_M);	/* maybe should be _D */
398*5c51f124SMoriah Waterland }
399*5c51f124SMoriah Waterland 
400*5c51f124SMoriah Waterland ^read/[\t\n ]		|
401*5c51f124SMoriah Waterland [\t ]read/[\t\n ]	|
402*5c51f124SMoriah Waterland "=[ ]+&<"[\t ]	{
403*5c51f124SMoriah Waterland 	if (status.in_pipe == 1 || status.allow_int == 1)
404*5c51f124SMoriah Waterland 		return (INITVAL);
405*5c51f124SMoriah Waterland 	else
406*5c51f124SMoriah Waterland 		return (INTERACT_M);
407*5c51f124SMoriah Waterland }
408*5c51f124SMoriah Waterland 
409*5c51f124SMoriah Waterland %{
410*5c51f124SMoriah Waterland /* Scan for root authority commands. Definite's first, maybe's next. */
411*5c51f124SMoriah Waterland %}
412*5c51f124SMoriah Waterland ^mkdir/[\t\n ]		|
413*5c51f124SMoriah Waterland [\t \/]mkdir/[\t\n ]	|
414*5c51f124SMoriah Waterland ^mv/[\t\n ]		|
415*5c51f124SMoriah Waterland [\t \/]mv/[\t\n ]	|
416*5c51f124SMoriah Waterland ^cpio/[\t\n ]		|
417*5c51f124SMoriah Waterland [\t \/]cpio/[\t\n ]	|
418*5c51f124SMoriah Waterland ^tar/[\t\n ]		|
419*5c51f124SMoriah Waterland [\t \/]tar/[\t\n ]	|
420*5c51f124SMoriah Waterland ^(un)?compress/[\t\n ]	|
421*5c51f124SMoriah Waterland [\t \/](un)?compress/[\t\n ]	|
422*5c51f124SMoriah Waterland ^rmdir/[\t\n ]		|
423*5c51f124SMoriah Waterland [\t \/]rmdir/[\t\n ]	return (ROOT_D);
424*5c51f124SMoriah Waterland 
425*5c51f124SMoriah Waterland ^r?cp(dir)?/[\t\n ]	|
426*5c51f124SMoriah Waterland [\t \/]r?cp(dir)?/[\t\n ]	|
427*5c51f124SMoriah Waterland ^rm/[\t\n ]	|
428*5c51f124SMoriah Waterland [\t \/]rm/[\t\n ]	|
429*5c51f124SMoriah Waterland \>[ \t]*[\$\/a-zA-Z0-9]	return (ROOT_M);
430*5c51f124SMoriah Waterland 
431*5c51f124SMoriah Waterland %{
432*5c51f124SMoriah Waterland /* These root commands may also be locked. */
433*5c51f124SMoriah Waterland 
434*5c51f124SMoriah Waterland /* Here we analyze any pkgchk calls. If it's "pkgchk ... -f ..." then that calls for root authority. We then check for a "-R" argument. */
435*5c51f124SMoriah Waterland %}
436*5c51f124SMoriah Waterland ^pkgchk[^\n^|^>^;]*"-f"	|
437*5c51f124SMoriah Waterland [\t \/]pkgchk[^\n^|^>^;]*"-f"	{
438*5c51f124SMoriah Waterland 	status.pkgchk_f = 1;
439*5c51f124SMoriah Waterland 	REJECT;		/* We need the intermediate args. */
440*5c51f124SMoriah Waterland }
441*5c51f124SMoriah Waterland 
442*5c51f124SMoriah Waterland %{
443*5c51f124SMoriah Waterland /* If it's "pkgchk ... -R ..." then the local package database is not being tested and no database warning is necessary. */
444*5c51f124SMoriah Waterland %}
445*5c51f124SMoriah Waterland ^pkgchk[^\n^|^>^;]*"-R"[ \t][\/\$]/[^ ^\t^\n]		|
446*5c51f124SMoriah Waterland [\t \/]pkgchk[^\n^|^>^;]*"-R"[ \t][\/\$]/[^ ^\t^\n]  {
447*5c51f124SMoriah Waterland 	if (status.pkgchk_f)
448*5c51f124SMoriah Waterland 		return (ROOT_D);
449*5c51f124SMoriah Waterland 	else
450*5c51f124SMoriah Waterland 		return (INITVAL);
451*5c51f124SMoriah Waterland }
452*5c51f124SMoriah Waterland 
453*5c51f124SMoriah Waterland %{
454*5c51f124SMoriah Waterland /* If it's just "pkgchk ..." then we need to mention something about access to the package database. With Solaris 2.5, an improved locking mechanism is in place, so this message may be something we can drop later. */
455*5c51f124SMoriah Waterland %}
456*5c51f124SMoriah Waterland ^pkgchk/[\t\n ]		|
457*5c51f124SMoriah Waterland [\t \/]pkgchk/[\t\n ]  {
458*5c51f124SMoriah Waterland 	if (status.pkgchk_f) {
459*5c51f124SMoriah Waterland 		status.pkgchk_f = 0;
460*5c51f124SMoriah Waterland 		return (ROOT_D | PKGDB_M);
461*5c51f124SMoriah Waterland 	} else
462*5c51f124SMoriah Waterland 		return (PKGDB_M);
463*5c51f124SMoriah Waterland }
464*5c51f124SMoriah Waterland 
465*5c51f124SMoriah Waterland %{
466*5c51f124SMoriah Waterland /* The installf and removef utilities require root authority, they modify the package database and they must be invoked at least once with a "-f" argument. */
467*5c51f124SMoriah Waterland 
468*5c51f124SMoriah Waterland /* First test for a "-f" argument. */
469*5c51f124SMoriah Waterland %}
470*5c51f124SMoriah Waterland ^installf[^\n^|^>^;]*"-f"	|
471*5c51f124SMoriah Waterland [\t \/]installf[^\n^|^>^;]*"-f"	{
472*5c51f124SMoriah Waterland 	status.instf_f = 1;
473*5c51f124SMoriah Waterland 
474*5c51f124SMoriah Waterland 	REJECT;		/* The whole line needs to be re-reviewed. */
475*5c51f124SMoriah Waterland }
476*5c51f124SMoriah Waterland 
477*5c51f124SMoriah Waterland ^removef[^\n^|^>^;]*"-f"	|
478*5c51f124SMoriah Waterland [\t \/]removef[^\n^|^>^;]*"-f"	{
479*5c51f124SMoriah Waterland 	status.remf_f = 1;
480*5c51f124SMoriah Waterland 
481*5c51f124SMoriah Waterland 	REJECT;		/* The whole line needs to be re-reviewed. */
482*5c51f124SMoriah Waterland }
483*5c51f124SMoriah Waterland 
484*5c51f124SMoriah Waterland ^installf/[\t\n ]	|
485*5c51f124SMoriah Waterland [\t \/]installf/[\t\n ]	{
486*5c51f124SMoriah Waterland 	status.instf = 1;
487*5c51f124SMoriah Waterland 	status.needspacefile = 1;
488*5c51f124SMoriah Waterland 
489*5c51f124SMoriah Waterland 	root_level = ROOT_D;
490*5c51f124SMoriah Waterland 	lock_level = LOCKED_M;
491*5c51f124SMoriah Waterland 
492*5c51f124SMoriah Waterland 	BEGIN WHROOT;
493*5c51f124SMoriah Waterland }
494*5c51f124SMoriah Waterland 
495*5c51f124SMoriah Waterland ^removef/[\t\n ]	|
496*5c51f124SMoriah Waterland [\t \/]removef/[\t\n ]	{
497*5c51f124SMoriah Waterland 	status.remf = 1;
498*5c51f124SMoriah Waterland 
499*5c51f124SMoriah Waterland 	root_level = ROOT_D;
500*5c51f124SMoriah Waterland 	lock_level = LOCKED_M;
501*5c51f124SMoriah Waterland 	BEGIN WHROOT;
502*5c51f124SMoriah Waterland }
503*5c51f124SMoriah Waterland 
504*5c51f124SMoriah Waterland %{
505*5c51f124SMoriah Waterland /* There's no question that use of a pkgadd or pkgrm in a script is bound to cause problems unless it is to a different root. */
506*5c51f124SMoriah Waterland %}
507*5c51f124SMoriah Waterland ^pkgadd/[\t\n ]	|
508*5c51f124SMoriah Waterland [\t \/]pkgadd/[\t\n ]	|
509*5c51f124SMoriah Waterland ^pkgrm/[\t\n ]		|
510*5c51f124SMoriah Waterland [\t \/]pkgrm/[\t\n ] {
511*5c51f124SMoriah Waterland 	root_level = ROOT_D;
512*5c51f124SMoriah Waterland 	lock_level = LOCKED_D;
513*5c51f124SMoriah Waterland 	BEGIN WHROOT;
514*5c51f124SMoriah Waterland }
515*5c51f124SMoriah Waterland 
516*5c51f124SMoriah Waterland %{
517*5c51f124SMoriah Waterland /* The only way to get here is if we are in the middle of a pkg command. */
518*5c51f124SMoriah Waterland %}
519*5c51f124SMoriah Waterland <WHROOT>. {
520*5c51f124SMoriah Waterland 	if (status.pkg_rtn_done) {
521*5c51f124SMoriah Waterland 		status.pkg_rtn_done = 0;
522*5c51f124SMoriah Waterland 		BEGIN 0;
523*5c51f124SMoriah Waterland 	} else
524*5c51f124SMoriah Waterland 		REJECT;
525*5c51f124SMoriah Waterland }
526*5c51f124SMoriah Waterland <WHROOT>[ \t]+"-R"[ \t][\/\$]/[^ ^\t^\n] {
527*5c51f124SMoriah Waterland 	status.pkg_rtn_done = 1;
528*5c51f124SMoriah Waterland 	return (root_level);		/* "-R" means locking is unlikely. */
529*5c51f124SMoriah Waterland }
530*5c51f124SMoriah Waterland <WHROOT>[\n]		{
531*5c51f124SMoriah Waterland 	if (status.pkg_rtn_done) {
532*5c51f124SMoriah Waterland 		status.pkg_rtn_done = 0;
533*5c51f124SMoriah Waterland 		line_no++;
534*5c51f124SMoriah Waterland 		BEGIN 0;
535*5c51f124SMoriah Waterland 	} else {
536*5c51f124SMoriah Waterland 		status.pkg_rtn_done = 1;
537*5c51f124SMoriah Waterland 		unput('\n');
538*5c51f124SMoriah Waterland 		return (root_level | lock_level); /* No "-R". */
539*5c51f124SMoriah Waterland 	}
540*5c51f124SMoriah Waterland }
541*5c51f124SMoriah Waterland <WHROOT>[;|>]		{
542*5c51f124SMoriah Waterland 	status.pkg_rtn_done = 1;
543*5c51f124SMoriah Waterland 	return (root_level | lock_level); /* End of command without a "-R". */
544*5c51f124SMoriah Waterland }
545*5c51f124SMoriah Waterland 
546*5c51f124SMoriah Waterland \n	{ line_no++; status.allow_int = 0; }
547*5c51f124SMoriah Waterland .	status.allow_int = 0;
548*5c51f124SMoriah Waterland %%
549*5c51f124SMoriah Waterland #include <stdio.h>
550*5c51f124SMoriah Waterland #include <limits.h>
551*5c51f124SMoriah Waterland #include <dirent.h>
552*5c51f124SMoriah Waterland #include <unistd.h>
553*5c51f124SMoriah Waterland #include <libintl.h>
554*5c51f124SMoriah Waterland 
555*5c51f124SMoriah Waterland #ifdef DEBUG
556*5c51f124SMoriah Waterland /*
557*5c51f124SMoriah Waterland  * Since this is a lex specification twice removed from the binary,
558*5c51f124SMoriah Waterland  * I strongly recommend leaving the DEBUG portions in place. When new
559*5c51f124SMoriah Waterland  * keywords are added, this will be very important. After modifying
560*5c51f124SMoriah Waterland  * the specification, create an executable to test in this way.
561*5c51f124SMoriah Waterland  *
562*5c51f124SMoriah Waterland  *	lex scriptvfy.l
563*5c51f124SMoriah Waterland  *	cc -o scriptvfy -g lex.yy.c $ROOT/usr/lib/libpkg.a \
564*5c51f124SMoriah Waterland  *	    -DDEBUG [-DVERBOSE] -ll -lintl
565*5c51f124SMoriah Waterland  *	scriptvfy test_directory
566*5c51f124SMoriah Waterland  */
567*5c51f124SMoriah Waterland 
568*5c51f124SMoriah Waterland main(int argc, char *argv[])
569*5c51f124SMoriah Waterland {
570*5c51f124SMoriah Waterland 	int val;
571*5c51f124SMoriah Waterland 
572*5c51f124SMoriah Waterland 	line_no = 1;
573*5c51f124SMoriah Waterland 
574*5c51f124SMoriah Waterland 	if (argc == 1) {
575*5c51f124SMoriah Waterland 		printf("No directory provided.\n");
576*5c51f124SMoriah Waterland 		exit(1);
577*5c51f124SMoriah Waterland 	}
578*5c51f124SMoriah Waterland 
579*5c51f124SMoriah Waterland 	val = checkscripts(argv[1], 0);
580*5c51f124SMoriah Waterland 
581*5c51f124SMoriah Waterland 	printf("return code is %d\n", val);
582*5c51f124SMoriah Waterland }
583*5c51f124SMoriah Waterland #endif
584*5c51f124SMoriah Waterland 
585*5c51f124SMoriah Waterland /*
586*5c51f124SMoriah Waterland  * This function evaluates the provided script and returns a bit string
587*5c51f124SMoriah Waterland  * describing what patterns were located.
588*5c51f124SMoriah Waterland  */
589*5c51f124SMoriah Waterland static int
590*5c51f124SMoriah Waterland scripteval(char *script_name, char *script_path, int mask, int silent)
591*5c51f124SMoriah Waterland {
592*5c51f124SMoriah Waterland 	int val = 0;
593*5c51f124SMoriah Waterland 	int error = 0;
594*5c51f124SMoriah Waterland 	line_no = 1;
595*5c51f124SMoriah Waterland 
596*5c51f124SMoriah Waterland 	if ((script_path == NULL) || (*script_path == NULL) ||
597*5c51f124SMoriah Waterland 	    (script_name == NULL)) {
598*5c51f124SMoriah Waterland 		logerr(gettext(ERR_ARGS));
599*5c51f124SMoriah Waterland 		return (0);
600*5c51f124SMoriah Waterland 	}
601*5c51f124SMoriah Waterland 
602*5c51f124SMoriah Waterland #ifdef VERBOSE
603*5c51f124SMoriah Waterland 	printf("Evaluating %s\n", script_path);
604*5c51f124SMoriah Waterland #endif
605*5c51f124SMoriah Waterland 
606*5c51f124SMoriah Waterland 	if ((scr_fp = fopen(script_path, "r")) == NULL) {
607*5c51f124SMoriah Waterland 		logerr(gettext(ERR_FOPEN), script_path, errno);
608*5c51f124SMoriah Waterland 		return (0);
609*5c51f124SMoriah Waterland 	}
610*5c51f124SMoriah Waterland 
611*5c51f124SMoriah Waterland #ifdef VERBOSE
612*5c51f124SMoriah Waterland 	printf("Openned script\n");
613*5c51f124SMoriah Waterland #endif
614*5c51f124SMoriah Waterland 
615*5c51f124SMoriah Waterland 	while (val = yylex()) {
616*5c51f124SMoriah Waterland #ifdef VERBOSE
617*5c51f124SMoriah Waterland 		printf("  Match is %s, returned 0x%x at line %d\n",
618*5c51f124SMoriah Waterland 		    yytext, val, line_no);
619*5c51f124SMoriah Waterland 		printf("    in_function = %d, in_awk = %d, in_loop = %d, " \
620*5c51f124SMoriah Waterland 		    "in_case = %d, in_if = %d, in_pipe = %d\n",
621*5c51f124SMoriah Waterland 		    status.in_function, status.in_awk, status.in_loop,
622*5c51f124SMoriah Waterland 		    status.in_case, status.in_if, status.in_pipe);
623*5c51f124SMoriah Waterland 		printf("    loop_depth = %d, case_depth = %d, " \
624*5c51f124SMoriah Waterland 		    "if_depth = %d, pipe_release = %d, cur_level = %d\n",
625*5c51f124SMoriah Waterland 		    loop_depth, case_depth, if_depth, pipe_release, cur_level);
626*5c51f124SMoriah Waterland #endif
627*5c51f124SMoriah Waterland 
628*5c51f124SMoriah Waterland 		val &= mask;
629*5c51f124SMoriah Waterland 		if (val) {
630*5c51f124SMoriah Waterland 			error |= ((val & MAYBE_ONLY) ? 1 : 2);
631*5c51f124SMoriah Waterland 
632*5c51f124SMoriah Waterland 			/*
633*5c51f124SMoriah Waterland 			 * So at this point, val contains all status bits
634*5c51f124SMoriah Waterland 			 * appropriate to this script.
635*5c51f124SMoriah Waterland 			 */
636*5c51f124SMoriah Waterland 			if (!silent) {
637*5c51f124SMoriah Waterland 				char *msg_ptr;
638*5c51f124SMoriah Waterland 				if (val & INTERACT_D)
639*5c51f124SMoriah Waterland 					msg_ptr = gettext(ERR_INTERACT);
640*5c51f124SMoriah Waterland 				else if (val & ROOT_D)
641*5c51f124SMoriah Waterland 					msg_ptr = gettext(ERR_ROOT);
642*5c51f124SMoriah Waterland 				else if (val & LOCKED_D)
643*5c51f124SMoriah Waterland 					msg_ptr = gettext(ERR_LOCKED);
644*5c51f124SMoriah Waterland 				else if (val & INTERACT_M)
645*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_INTERACT);
646*5c51f124SMoriah Waterland 				else if (val & ROOT_M)
647*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_ROOT);
648*5c51f124SMoriah Waterland 				else if (val & LOCKED_M)
649*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_LOCKED);
650*5c51f124SMoriah Waterland 				else if (val & WPARM1_M)
651*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_FORM_USE);
652*5c51f124SMoriah Waterland 				else if (val & USEPARM1_M)
653*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_FORM_USE);
654*5c51f124SMoriah Waterland 				else if (val &  ODDPARM_M)
655*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_FORM_ARG);
656*5c51f124SMoriah Waterland 				else if (val &  PKGDB_M)
657*5c51f124SMoriah Waterland 					msg_ptr = gettext(WRN_TRANSDB);
658*5c51f124SMoriah Waterland 				else
659*5c51f124SMoriah Waterland 					msg_ptr = gettext("unknown error");
660*5c51f124SMoriah Waterland 
661*5c51f124SMoriah Waterland 				logerr(msg_ptr, script_name, line_no);
662*5c51f124SMoriah Waterland 			}
663*5c51f124SMoriah Waterland 		}
664*5c51f124SMoriah Waterland 	}
665*5c51f124SMoriah Waterland 
666*5c51f124SMoriah Waterland 	/* Warn if required about missing "-f" calls. */
667*5c51f124SMoriah Waterland 	if (status.instf && !(status.instf_f))
668*5c51f124SMoriah Waterland 		logerr(gettext(WRN_INST_F), script_name);
669*5c51f124SMoriah Waterland 
670*5c51f124SMoriah Waterland 	if (status.remf && !(status.remf_f))
671*5c51f124SMoriah Waterland 		logerr(gettext(WRN_REM_F), script_name);
672*5c51f124SMoriah Waterland 
673*5c51f124SMoriah Waterland 	status.instf = status.instf_f = status.remf = status.remf_f = 0;
674*5c51f124SMoriah Waterland 
675*5c51f124SMoriah Waterland 	/* Warn if installf was used but no space file is in place. */
676*5c51f124SMoriah Waterland 	if (status.nospacefile && status.needspacefile) {
677*5c51f124SMoriah Waterland 		logerr(gettext(WRN_SPACEACC), script_name);
678*5c51f124SMoriah Waterland 		status.needspacefile = 0;
679*5c51f124SMoriah Waterland 	}
680*5c51f124SMoriah Waterland 
681*5c51f124SMoriah Waterland 	status.in_pipe = 0;	/* Pipes may dangle. */
682*5c51f124SMoriah Waterland 	fclose(scr_fp);
683*5c51f124SMoriah Waterland 
684*5c51f124SMoriah Waterland 	if (error == 3)
685*5c51f124SMoriah Waterland 		error = 2;
686*5c51f124SMoriah Waterland 
687*5c51f124SMoriah Waterland 	return (error);
688*5c51f124SMoriah Waterland }
689*5c51f124SMoriah Waterland 
690*5c51f124SMoriah Waterland /* Test a preinstall or preremove script for validity. */
691*5c51f124SMoriah Waterland int
692*5c51f124SMoriah Waterland pre_valid(char *script_name, char *script_path, int silent)
693*5c51f124SMoriah Waterland {
694*5c51f124SMoriah Waterland 	return (scripteval(script_name, script_path, PRE_MASK, silent));
695*5c51f124SMoriah Waterland }
696*5c51f124SMoriah Waterland 
697*5c51f124SMoriah Waterland /* Test a class action script for validity. */
698*5c51f124SMoriah Waterland int
699*5c51f124SMoriah Waterland cas_valid(char *script_name, char *script_path, int silent)
700*5c51f124SMoriah Waterland {
701*5c51f124SMoriah Waterland 	return (scripteval(script_name, script_path, CAS_MASK, silent));
702*5c51f124SMoriah Waterland }
703*5c51f124SMoriah Waterland 
704*5c51f124SMoriah Waterland /* Test a postinstall or postremove script for validity. */
705*5c51f124SMoriah Waterland int
706*5c51f124SMoriah Waterland post_valid(char *script_name, char *script_path, int silent)
707*5c51f124SMoriah Waterland {
708*5c51f124SMoriah Waterland 	return (scripteval(script_name, script_path, POST_MASK, silent));
709*5c51f124SMoriah Waterland }
710*5c51f124SMoriah Waterland 
711*5c51f124SMoriah Waterland /* Test a class action script for validity. */
712*5c51f124SMoriah Waterland int
713*5c51f124SMoriah Waterland req_valid(char *script_name, char *script_path, int silent)
714*5c51f124SMoriah Waterland {
715*5c51f124SMoriah Waterland 	return (scripteval(script_name, script_path, REQ_MASK, silent));
716*5c51f124SMoriah Waterland }
717*5c51f124SMoriah Waterland 
718*5c51f124SMoriah Waterland 
719*5c51f124SMoriah Waterland /* Test a class action script for validity. */
720*5c51f124SMoriah Waterland int
721*5c51f124SMoriah Waterland chk_valid(char *script_name, char *script_path, int silent)
722*5c51f124SMoriah Waterland {
723*5c51f124SMoriah Waterland 	return (scripteval(script_name, script_path, CHK_MASK, silent));
724*5c51f124SMoriah Waterland }
725*5c51f124SMoriah Waterland 
726*5c51f124SMoriah Waterland /* This tests all of the scripts in the provided directory. */
727*5c51f124SMoriah Waterland int
728*5c51f124SMoriah Waterland checkscripts(char *inst_dir, int silent)
729*5c51f124SMoriah Waterland {
730*5c51f124SMoriah Waterland 	DIR *dirfp;
731*5c51f124SMoriah Waterland 	struct dirent *dp;
732*5c51f124SMoriah Waterland 	char path[PATH_MAX];
733*5c51f124SMoriah Waterland 	int retval = 0;
734*5c51f124SMoriah Waterland 
735*5c51f124SMoriah Waterland 	/* For future reference, determine if a space file is present. */
736*5c51f124SMoriah Waterland 	sprintf(path, "%s/%s", inst_dir, "space");
737*5c51f124SMoriah Waterland 	if (access(path, F_OK) != 0)
738*5c51f124SMoriah Waterland 		status.nospacefile = 1;
739*5c51f124SMoriah Waterland 
740*5c51f124SMoriah Waterland 	if ((dirfp = opendir(inst_dir)) == NULL)
741*5c51f124SMoriah Waterland 		return (0);
742*5c51f124SMoriah Waterland 
743*5c51f124SMoriah Waterland 	while ((dp = readdir(dirfp)) != NULL) {
744*5c51f124SMoriah Waterland #ifdef VERBOSE
745*5c51f124SMoriah Waterland 		printf("Looking at file %s\n", dp->d_name);
746*5c51f124SMoriah Waterland #endif
747*5c51f124SMoriah Waterland 		if (dp->d_name[0] == '.')
748*5c51f124SMoriah Waterland 			continue;
749*5c51f124SMoriah Waterland 
750*5c51f124SMoriah Waterland 		if ((strcmp(dp->d_name, "preinstall") == 0) ||
751*5c51f124SMoriah Waterland 		    (strcmp(dp->d_name, "preremove") == 0)) {
752*5c51f124SMoriah Waterland 			sprintf(path, "%s/%s", inst_dir, dp->d_name);
753*5c51f124SMoriah Waterland 			retval |= pre_valid(dp->d_name, path, silent);
754*5c51f124SMoriah Waterland 			continue;
755*5c51f124SMoriah Waterland 		}
756*5c51f124SMoriah Waterland 
757*5c51f124SMoriah Waterland 		if ((strncmp(dp->d_name, "i.", 2) == 0) ||
758*5c51f124SMoriah Waterland 		    (strncmp(dp->d_name, "r.", 2) == 0)) {
759*5c51f124SMoriah Waterland 			sprintf(path, "%s/%s", inst_dir, dp->d_name);
760*5c51f124SMoriah Waterland 			retval |= cas_valid(dp->d_name, path, silent);
761*5c51f124SMoriah Waterland 			continue;
762*5c51f124SMoriah Waterland 		}
763*5c51f124SMoriah Waterland 
764*5c51f124SMoriah Waterland 		if ((strcmp(dp->d_name, "postinstall") == 0) ||
765*5c51f124SMoriah Waterland 		    (strcmp(dp->d_name, "postremove") == 0)) {
766*5c51f124SMoriah Waterland 			sprintf(path, "%s/%s", inst_dir, dp->d_name);
767*5c51f124SMoriah Waterland 			retval |= post_valid(dp->d_name, path, silent);
768*5c51f124SMoriah Waterland 			continue;
769*5c51f124SMoriah Waterland 		}
770*5c51f124SMoriah Waterland 
771*5c51f124SMoriah Waterland 		if (strcmp(dp->d_name, "request") == 0) {
772*5c51f124SMoriah Waterland 			sprintf(path, "%s/%s", inst_dir, dp->d_name);
773*5c51f124SMoriah Waterland 			retval |= req_valid(dp->d_name, path, silent);
774*5c51f124SMoriah Waterland 			continue;
775*5c51f124SMoriah Waterland 		}
776*5c51f124SMoriah Waterland 		if (strcmp(dp->d_name, "checkinstall") == 0) {
777*5c51f124SMoriah Waterland 			sprintf(path, "%s/%s", inst_dir, dp->d_name);
778*5c51f124SMoriah Waterland 			retval |= chk_valid(dp->d_name, path, silent);
779*5c51f124SMoriah Waterland 			continue;
780*5c51f124SMoriah Waterland 		}
781*5c51f124SMoriah Waterland 	}
782*5c51f124SMoriah Waterland 
783*5c51f124SMoriah Waterland 	(void) closedir(dirfp);
784*5c51f124SMoriah Waterland 
785*5c51f124SMoriah Waterland 	return (retval);
786*5c51f124SMoriah Waterland }
787