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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2017 Peter Tribble.
24  */
25 
26 /*
27  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
33 
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include <utmpx.h>
40 #include <dirent.h>
41 #include <sys/types.h>
42 #include <pkgstrct.h>
43 #include <locale.h>
44 #include <libintl.h>
45 #include "install.h"
46 #include <pkglib.h>
47 #include "libadm.h"
48 #include "libinst.h"
49 #include "messages.h"
50 
51 extern struct admin adm;
52 
53 extern char	pkgloc[], *pkginst, *msgtext;
54 
55 static boolean_t	preremoveCheck = B_FALSE;
56 static char		*zoneName = (char *)NULL;
57 
58 
59 void
60 rcksetPreremoveCheck(boolean_t a_preremoveCheck)
61 {
62 	preremoveCheck = a_preremoveCheck;
63 }
64 
65 void
66 rcksetZoneName(char *a_zoneName)
67 {
68 	zoneName = a_zoneName;
69 }
70 
71 int
72 rckrunlevel(void)
73 {
74 	struct utmpx utmpx;
75 	struct utmpx *putmpx;
76 	char	ans[MAX_INPUT];
77 	char	*pt;
78 	char	*rstates;
79 	int	n;
80 	char	*uxstate;
81 
82 	if (ADM(runlevel, "nocheck")) {
83 		return (0);
84 	}
85 
86 	pt = getenv("RSTATES");
87 	if (pt == NULL) {
88 		return (0);
89 	}
90 
91 	utmpx.ut_type = RUN_LVL;
92 	putmpx = getutxid(&utmpx);
93 	if (putmpx == NULL) {
94 		progerr(ERR_RUNSTATE);
95 		return (99);
96 	}
97 	uxstate = strtok(&putmpx->ut_line[10], " \t\n");
98 
99 	rstates = qstrdup(pt);
100 	if ((pt = strtok(pt, " \t\n, ")) == NULL)
101 		return (0); /* no list is no list */
102 	do {
103 		if (strcmp(pt, uxstate) == NULL) {
104 			free(rstates);
105 			return (0);
106 		}
107 	} while (pt = strtok(NULL, " \t\n, "));
108 
109 	if (preremoveCheck == B_FALSE) {
110 		msgtext = MSG_PKGREMOVE_RUNLEVEL;
111 		ptext(stderr, msgtext, uxstate);
112 	} else {
113 		(void) fprintf(stdout, "runlevel=%s", uxstate);
114 	}
115 
116 	pt = strtok(rstates, " \t\n, ");
117 	do {
118 		if (preremoveCheck == B_FALSE) {
119 			ptext(stderr, "\\t%s", pt);
120 		} else {
121 			(void) fprintf(stdout, ":%s", pt);
122 		}
123 	} while (pt = strtok(NULL, " \t\n, "));
124 
125 	if (preremoveCheck == B_TRUE) {
126 		(void) fprintf(stdout, "\n");
127 	}
128 
129 	free(rstates);
130 
131 	if (ADM(runlevel, "quit")) {
132 		return (4);
133 	}
134 
135 	if (echoGetFlag() == B_FALSE) {
136 		return (5);
137 	}
138 
139 	msgtext = NULL;
140 
141 	n = ckyorn(ans, NULL, NULL, HLP_PKGREMOVE_RUNLEVEL,
142 	    ASK_PKGREMOVE_CONTINUE);
143 
144 	if (n != 0) {
145 		return (n);
146 	}
147 
148 	if (strchr("yY", *ans) == NULL) {
149 		return (3);
150 	}
151 
152 	return (0);
153 }
154 
155 int
156 rckdepend(void)
157 {
158 	int	n;
159 	char	ans[MAX_INPUT];
160 
161 	if (ADM(rdepend, "nocheck")) {
162 		return (0);
163 	}
164 
165 	if (zoneName == (char *)NULL) {
166 		echo(MSG_CHECKREMOVE_PKG_IN_GZ, pkginst);
167 	} else {
168 		echo(MSG_CHECKREMOVE_PKG_IN_ZONE, pkginst, zoneName);
169 	}
170 
171 	if (dockdeps(pkginst, 1, preremoveCheck)) {
172 		msgtext = MSG_PKGREMOVE_DEPEND;
173 
174 		if (preremoveCheck == B_FALSE) {
175 			echo(msgtext);
176 		}
177 
178 		if (ADM(rdepend, "quit")) {
179 			return (4);
180 		}
181 
182 		if (echoGetFlag() == B_FALSE) {
183 			return (5);
184 		}
185 
186 		msgtext = NULL;
187 
188 		n = ckyorn(ans, NULL, NULL, HLP_PKGREMOVE_DEPEND,
189 		    ASK_PKGREMOVE_CONTINUE);
190 
191 		if (n != 0) {
192 			return (n);
193 		}
194 
195 		if (strchr("yY", *ans) == NULL) {
196 			return (3);
197 		}
198 	}
199 
200 	return (0);
201 }
202 
203 int
204 rckpriv(void)
205 {
206 	struct dirent	*dp;
207 	DIR		*dirfp;
208 	int		n;
209 	char		found;
210 	char		ans[MAX_INPUT];
211 	char		path[PATH_MAX];
212 
213 	if (ADM(action, "nocheck")) {
214 		return (0);
215 	}
216 
217 	(void) snprintf(path, sizeof (path), "%s/install", pkgloc);
218 	if ((dirfp = opendir(path)) == NULL)
219 		return (0);
220 
221 	found = 0;
222 	while ((dp = readdir(dirfp)) != NULL) {
223 		if ((strcmp(dp->d_name, "preremove") == NULL) ||
224 		    (strcmp(dp->d_name, "postremove") == NULL) ||
225 		    (strncmp(dp->d_name, "r.", 2) == NULL)) {
226 			found++;
227 			break;
228 		}
229 	}
230 	(void) closedir(dirfp);
231 
232 	if (found) {
233 		if (preremoveCheck == B_FALSE) {
234 			ptext(stderr, MSG_PKGREMOVE_PRIV);
235 		}
236 		msgtext = MSG_PKGSCRIPTS_FOUND;
237 
238 		if (ADM(action, "quit")) {
239 			return (4);
240 		}
241 
242 		if (echoGetFlag() == B_FALSE) {
243 			return (5);
244 		}
245 
246 		msgtext = NULL;
247 
248 		n = ckyorn(ans, NULL, NULL, HLP_PKGREMOVE_PRIV,
249 		    ASK_PKGREMOVE_CONTINUE);
250 
251 		if (n != 0) {
252 			return (n);
253 		}
254 
255 		if (strchr("yY", *ans) == NULL) {
256 			return (3);
257 		}
258 	}
259 
260 	return (0);
261 }
262