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 2009 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 #include <stdio.h>
29*5c51f124SMoriah Waterland #include <limits.h>
30*5c51f124SMoriah Waterland #include <string.h>
31*5c51f124SMoriah Waterland #include <stdlib.h>
32*5c51f124SMoriah Waterland #include <sys/stat.h>
33*5c51f124SMoriah Waterland #include <unistd.h>
34*5c51f124SMoriah Waterland #include <errno.h>
35*5c51f124SMoriah Waterland #include <utmpx.h>
36*5c51f124SMoriah Waterland #include <dirent.h>
37*5c51f124SMoriah Waterland #include <sys/types.h>
38*5c51f124SMoriah Waterland #include <locale.h>
39*5c51f124SMoriah Waterland #include <libintl.h>
40*5c51f124SMoriah Waterland #include <pkgstrct.h>
41*5c51f124SMoriah Waterland #include <pkglocs.h>
42*5c51f124SMoriah Waterland #include <assert.h>
43*5c51f124SMoriah Waterland #include <pkglib.h>
44*5c51f124SMoriah Waterland #include <install.h>
45*5c51f124SMoriah Waterland #include <libinst.h>
46*5c51f124SMoriah Waterland #include <libadm.h>
47*5c51f124SMoriah Waterland #include <messages.h>
48*5c51f124SMoriah Waterland #include <instzones_api.h>
49*5c51f124SMoriah Waterland
50*5c51f124SMoriah Waterland extern int npkgs; /* the number of packages yet to be installed */
51*5c51f124SMoriah Waterland
52*5c51f124SMoriah Waterland /*
53*5c51f124SMoriah Waterland * ckquit is a global that controls 'ckyorn' (defined in libadm)
54*5c51f124SMoriah Waterland * If ckquit is non-zero, then "quit" is allowed as an answer when
55*5c51f124SMoriah Waterland * ckyorn is called. If is it zero, then "quit" is not an allowed answer.
56*5c51f124SMoriah Waterland */
57*5c51f124SMoriah Waterland extern int ckquit;
58*5c51f124SMoriah Waterland
59*5c51f124SMoriah Waterland extern struct admin adm;
60*5c51f124SMoriah Waterland
61*5c51f124SMoriah Waterland /*
62*5c51f124SMoriah Waterland * each one of these represents a single kind of dependency check
63*5c51f124SMoriah Waterland */
64*5c51f124SMoriah Waterland
65*5c51f124SMoriah Waterland static depckError_t er_depsonme = {0, (depckErrorRecord_t *)NULL};
66*5c51f124SMoriah Waterland static depckError_t er_prenci = {0, (depckErrorRecord_t *)NULL};
67*5c51f124SMoriah Waterland static depckError_t er_prereq = {0, (depckErrorRecord_t *)NULL};
68*5c51f124SMoriah Waterland static depckError_t er_rckdepend = {0, (depckErrorRecord_t *)NULL};
69*5c51f124SMoriah Waterland static depckError_t er_rckpriv = {0, (depckErrorRecord_t *)NULL};
70*5c51f124SMoriah Waterland static depckError_t er_rckrunlevel = {0, (depckErrorRecord_t *)NULL};
71*5c51f124SMoriah Waterland static depckError_t er_runlevel = {0, (depckErrorRecord_t *)NULL};
72*5c51f124SMoriah Waterland
73*5c51f124SMoriah Waterland /*
74*5c51f124SMoriah Waterland * each one of these represents a localized message for a single kind
75*5c51f124SMoriah Waterland * of dependency check
76*5c51f124SMoriah Waterland */
77*5c51f124SMoriah Waterland
78*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_CKRUNLVL = (char *)NULL;
79*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_DEPEND = (char *)NULL;
80*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_DEPSONME = (char *)NULL;
81*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_PRENCI = (char *)NULL;
82*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_PREREQ = (char *)NULL;
83*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_PRIV = (char *)NULL;
84*5c51f124SMoriah Waterland static char *IMSG_PKGRMCHK_RUNLEVEL = (char *)NULL;
85*5c51f124SMoriah Waterland
86*5c51f124SMoriah Waterland /*
87*5c51f124SMoriah Waterland * each one of these represents a function to handle a single kind of
88*5c51f124SMoriah Waterland * dependency check
89*5c51f124SMoriah Waterland */
90*5c51f124SMoriah Waterland
91*5c51f124SMoriah Waterland static int rckdepend(char *a_msg, char *a_pkg);
92*5c51f124SMoriah Waterland static int rckdepsonme(char *a_msg, char *a_pkg);
93*5c51f124SMoriah Waterland static int rckprenci(char *a_msg, char *a_pkg);
94*5c51f124SMoriah Waterland static int rckprereq(char *a_msg, char *a_pkg);
95*5c51f124SMoriah Waterland static int rckpriv(char *a_msg, char *a_pkg);
96*5c51f124SMoriah Waterland static int rckrunlevel(char *a_msg, char *a_pkg);
97*5c51f124SMoriah Waterland
98*5c51f124SMoriah Waterland static depckl_t DEPCKL[] = {
99*5c51f124SMoriah Waterland /*
100*5c51f124SMoriah Waterland * Message hierarchy:
101*5c51f124SMoriah Waterland * -- runlevel=%s
102*5c51f124SMoriah Waterland * --- rckrunlevel=%d
103*5c51f124SMoriah Waterland * --- rckpriv=%d ****
104*5c51f124SMoriah Waterland * -- incompat=%s
105*5c51f124SMoriah Waterland * -- prerequisite-incomplete=%s
106*5c51f124SMoriah Waterland * -- dependonme=%s
107*5c51f124SMoriah Waterland * -- dependsonme=%s:%s
108*5c51f124SMoriah Waterland * -- prerequisite-installed=%s
109*5c51f124SMoriah Waterland * ---rckdepend=%d ****
110*5c51f124SMoriah Waterland */
111*5c51f124SMoriah Waterland
112*5c51f124SMoriah Waterland /* name, ignore_values, err_msg, depcklFunc, recrd */
113*5c51f124SMoriah Waterland /*
114*5c51f124SMoriah Waterland * package and zone information is collected in the "record" object for
115*5c51f124SMoriah Waterland * each occurance - then a message is constructed for each zone that
116*5c51f124SMoriah Waterland * reported the condition - the message includes that portion of the
117*5c51f124SMoriah Waterland * check past the "=" - then the specified "depcklFunc" is called to
118*5c51f124SMoriah Waterland * process each message.
119*5c51f124SMoriah Waterland * Message format:
120*5c51f124SMoriah Waterland * %s %s <%s> %s <%s>
121*5c51f124SMoriah Waterland * Message arguments:
122*5c51f124SMoriah Waterland * value, "package", package-name, "zone/zones", zone-name
123*5c51f124SMoriah Waterland */
124*5c51f124SMoriah Waterland
125*5c51f124SMoriah Waterland { "dependsonme=", NULL, &IMSG_PKGRMCHK_DEPSONME,
126*5c51f124SMoriah Waterland &rckdepsonme, &er_depsonme
127*5c51f124SMoriah Waterland },
128*5c51f124SMoriah Waterland { "dependonme=", NULL, &IMSG_PKGRMCHK_DEPSONME,
129*5c51f124SMoriah Waterland &rckdepsonme, &er_depsonme
130*5c51f124SMoriah Waterland },
131*5c51f124SMoriah Waterland { "prerequisite-incomplete=", NULL, &IMSG_PKGRMCHK_PRENCI,
132*5c51f124SMoriah Waterland &rckprenci, &er_prenci
133*5c51f124SMoriah Waterland },
134*5c51f124SMoriah Waterland { "prerequisite-installed=", NULL, &IMSG_PKGRMCHK_PREREQ,
135*5c51f124SMoriah Waterland &rckprereq, &er_prereq
136*5c51f124SMoriah Waterland },
137*5c51f124SMoriah Waterland { "runlevel=", NULL, &IMSG_PKGRMCHK_RUNLEVEL,
138*5c51f124SMoriah Waterland NULL, &er_runlevel
139*5c51f124SMoriah Waterland },
140*5c51f124SMoriah Waterland
141*5c51f124SMoriah Waterland /*
142*5c51f124SMoriah Waterland * these checks are ignored if they return one of the listed values
143*5c51f124SMoriah Waterland * if they do NOT return one of the listed values, then the package
144*5c51f124SMoriah Waterland * and zone information is collected in the "record" object for each
145*5c51f124SMoriah Waterland * occurance - then a single unified message is constructed for all
146*5c51f124SMoriah Waterland * zones that report the same condition; then the specified "depcklFunc"
147*5c51f124SMoriah Waterland * is called to process the resulting combined message.
148*5c51f124SMoriah Waterland * Message format:
149*5c51f124SMoriah Waterland * %s <%s> %s <%s>
150*5c51f124SMoriah Waterland * Message arguments:
151*5c51f124SMoriah Waterland * "package", package-name, "zone/zones", zone-name(s)
152*5c51f124SMoriah Waterland */
153*5c51f124SMoriah Waterland
154*5c51f124SMoriah Waterland { "rckdepend=", "0", &IMSG_PKGRMCHK_DEPEND,
155*5c51f124SMoriah Waterland &rckdepend, &er_rckdepend
156*5c51f124SMoriah Waterland },
157*5c51f124SMoriah Waterland { "rckpriv=", "0", &IMSG_PKGRMCHK_PRIV,
158*5c51f124SMoriah Waterland &rckpriv, &er_rckpriv
159*5c51f124SMoriah Waterland },
160*5c51f124SMoriah Waterland { "rckrunlevel=", "0", &IMSG_PKGRMCHK_CKRUNLVL,
161*5c51f124SMoriah Waterland &rckrunlevel, &er_rckrunlevel
162*5c51f124SMoriah Waterland },
163*5c51f124SMoriah Waterland
164*5c51f124SMoriah Waterland /*
165*5c51f124SMoriah Waterland * same as above BUT no check to ignore is done; message always reported
166*5c51f124SMoriah Waterland */
167*5c51f124SMoriah Waterland
168*5c51f124SMoriah Waterland { NULL, NULL, NULL,
169*5c51f124SMoriah Waterland NULL, NULL
170*5c51f124SMoriah Waterland }
171*5c51f124SMoriah Waterland };
172*5c51f124SMoriah Waterland
173*5c51f124SMoriah Waterland /*
174*5c51f124SMoriah Waterland * Name: preremove_verify
175*5c51f124SMoriah Waterland * Description: verify results of preremoval dependency checking
176*5c51f124SMoriah Waterland * Arguments: a_pkglist - pointer to array of strings representing the names
177*5c51f124SMoriah Waterland * of all the packages that have been checked
178*5c51f124SMoriah Waterland * a_zlst - list of zones that dependencies were checked on
179*5c51f124SMoriah Waterland * a_zoneTempDir - pointer to string representing the path where
180*5c51f124SMoriah Waterland * the files containing the preremoval dependency
181*5c51f124SMoriah Waterland * check data are located
182*5c51f124SMoriah Waterland * Returns: int
183*5c51f124SMoriah Waterland * == 0 - continue processing
184*5c51f124SMoriah Waterland * != 0 - do not continue processing
185*5c51f124SMoriah Waterland */
186*5c51f124SMoriah Waterland
187*5c51f124SMoriah Waterland int
preremove_verify(char ** a_pkglist,zoneList_t a_zlst,char * a_zoneTempDir)188*5c51f124SMoriah Waterland preremove_verify(char **a_pkglist, zoneList_t a_zlst, char *a_zoneTempDir)
189*5c51f124SMoriah Waterland {
190*5c51f124SMoriah Waterland char *pkginst;
191*5c51f124SMoriah Waterland int i;
192*5c51f124SMoriah Waterland int savenpkgs = npkgs;
193*5c51f124SMoriah Waterland
194*5c51f124SMoriah Waterland /*
195*5c51f124SMoriah Waterland * entry assertions
196*5c51f124SMoriah Waterland */
197*5c51f124SMoriah Waterland
198*5c51f124SMoriah Waterland assert(a_pkglist != (char **)NULL);
199*5c51f124SMoriah Waterland assert(a_zlst != (zoneList_t)NULL);
200*5c51f124SMoriah Waterland assert(a_zoneTempDir != (char *)NULL);
201*5c51f124SMoriah Waterland
202*5c51f124SMoriah Waterland /*
203*5c51f124SMoriah Waterland * entry debugging info
204*5c51f124SMoriah Waterland */
205*5c51f124SMoriah Waterland
206*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_ENTRY);
207*5c51f124SMoriah Waterland
208*5c51f124SMoriah Waterland /*
209*5c51f124SMoriah Waterland * localize messages
210*5c51f124SMoriah Waterland */
211*5c51f124SMoriah Waterland
212*5c51f124SMoriah Waterland IMSG_PKGRMCHK_DEPSONME = MSG_PKGRMCHK_DEPSONME;
213*5c51f124SMoriah Waterland IMSG_PKGRMCHK_PRENCI = MSG_PKGRMCHK_PRENCI;
214*5c51f124SMoriah Waterland IMSG_PKGRMCHK_PREREQ = MSG_PKGRMCHK_PREREQ;
215*5c51f124SMoriah Waterland IMSG_PKGRMCHK_RUNLEVEL = MSG_PKGRMCHK_RUNLEVEL;
216*5c51f124SMoriah Waterland IMSG_PKGRMCHK_DEPEND = MSG_PKGRMCHK_DEPEND;
217*5c51f124SMoriah Waterland IMSG_PKGRMCHK_PRIV = MSG_PKGRMCHK_PRIV;
218*5c51f124SMoriah Waterland IMSG_PKGRMCHK_CKRUNLVL = MSG_PKGRMCHK_CKRUNLVL;
219*5c51f124SMoriah Waterland
220*5c51f124SMoriah Waterland /*
221*5c51f124SMoriah Waterland * outer loop - process each package first
222*5c51f124SMoriah Waterland */
223*5c51f124SMoriah Waterland
224*5c51f124SMoriah Waterland for (i = 0; (pkginst = a_pkglist[i]) != NULL; i++) {
225*5c51f124SMoriah Waterland
226*5c51f124SMoriah Waterland char *zoneName;
227*5c51f124SMoriah Waterland int zoneIndex;
228*5c51f124SMoriah Waterland
229*5c51f124SMoriah Waterland /*
230*5c51f124SMoriah Waterland * inner loop - for each package process each zone second
231*5c51f124SMoriah Waterland */
232*5c51f124SMoriah Waterland
233*5c51f124SMoriah Waterland if (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE) {
234*5c51f124SMoriah Waterland continue;
235*5c51f124SMoriah Waterland }
236*5c51f124SMoriah Waterland
237*5c51f124SMoriah Waterland for (zoneIndex = 0;
238*5c51f124SMoriah Waterland (zoneName = z_zlist_get_zonename(a_zlst, zoneIndex)) !=
239*5c51f124SMoriah Waterland (char *)NULL; zoneIndex++) {
240*5c51f124SMoriah Waterland
241*5c51f124SMoriah Waterland FILE *fp;
242*5c51f124SMoriah Waterland char line[PATH_MAX+1];
243*5c51f124SMoriah Waterland char preremovecheckPath[PATH_MAX+1];
244*5c51f124SMoriah Waterland int len;
245*5c51f124SMoriah Waterland
246*5c51f124SMoriah Waterland /* skip the zone if it is NOT bootable */
247*5c51f124SMoriah Waterland
248*5c51f124SMoriah Waterland if (z_zlist_is_zone_runnable(a_zlst,
249*5c51f124SMoriah Waterland zoneIndex) == B_FALSE) {
250*5c51f124SMoriah Waterland continue;
251*5c51f124SMoriah Waterland }
252*5c51f124SMoriah Waterland
253*5c51f124SMoriah Waterland /* create path to this packages preremove check data */
254*5c51f124SMoriah Waterland
255*5c51f124SMoriah Waterland len = snprintf(preremovecheckPath,
256*5c51f124SMoriah Waterland sizeof (preremovecheckPath),
257*5c51f124SMoriah Waterland "%s/%s.%s.preremovecheck.txt",
258*5c51f124SMoriah Waterland a_zoneTempDir, pkginst,
259*5c51f124SMoriah Waterland z_zlist_get_scratch(a_zlst, zoneIndex));
260*5c51f124SMoriah Waterland
261*5c51f124SMoriah Waterland if (len > sizeof (preremovecheckPath)) {
262*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_3, a_zoneTempDir,
263*5c51f124SMoriah Waterland pkginst, zoneName);
264*5c51f124SMoriah Waterland continue;
265*5c51f124SMoriah Waterland }
266*5c51f124SMoriah Waterland
267*5c51f124SMoriah Waterland /* error if preremove check data path is not a file */
268*5c51f124SMoriah Waterland
269*5c51f124SMoriah Waterland if (isfile((char *)NULL, preremovecheckPath) != 0) {
270*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_NOFILE, pkginst, zoneName,
271*5c51f124SMoriah Waterland preremovecheckPath, strerror(errno));
272*5c51f124SMoriah Waterland progerr(ERR_PRERVFY_NOFILE, pkginst, zoneName);
273*5c51f124SMoriah Waterland continue;
274*5c51f124SMoriah Waterland }
275*5c51f124SMoriah Waterland
276*5c51f124SMoriah Waterland /* open the preremove check data file */
277*5c51f124SMoriah Waterland
278*5c51f124SMoriah Waterland fp = fopen(preremovecheckPath, "r");
279*5c51f124SMoriah Waterland if (fp == (FILE *)NULL) {
280*5c51f124SMoriah Waterland progerr(ERR_PRERVFY_OPEN_FILE,
281*5c51f124SMoriah Waterland preremovecheckPath, pkginst, zoneName,
282*5c51f124SMoriah Waterland strerror(errno));
283*5c51f124SMoriah Waterland continue;
284*5c51f124SMoriah Waterland }
285*5c51f124SMoriah Waterland
286*5c51f124SMoriah Waterland /* read and process each preremove check data line */
287*5c51f124SMoriah Waterland
288*5c51f124SMoriah Waterland while (fgets(line, sizeof (line), fp) != (char *)NULL) {
289*5c51f124SMoriah Waterland int len;
290*5c51f124SMoriah Waterland int j;
291*5c51f124SMoriah Waterland
292*5c51f124SMoriah Waterland /* remove all new-lines from end of line */
293*5c51f124SMoriah Waterland
294*5c51f124SMoriah Waterland len = strlen(line);
295*5c51f124SMoriah Waterland while ((len > 0) && (line[len-1] == '\n')) {
296*5c51f124SMoriah Waterland line[--len] = '\0';
297*5c51f124SMoriah Waterland }
298*5c51f124SMoriah Waterland
299*5c51f124SMoriah Waterland /* ignore comment lines */
300*5c51f124SMoriah Waterland
301*5c51f124SMoriah Waterland if (line[0] == '#') {
302*5c51f124SMoriah Waterland continue;
303*5c51f124SMoriah Waterland }
304*5c51f124SMoriah Waterland
305*5c51f124SMoriah Waterland /* ignore empty lines */
306*5c51f124SMoriah Waterland
307*5c51f124SMoriah Waterland if (line[0] == '\0') {
308*5c51f124SMoriah Waterland continue;
309*5c51f124SMoriah Waterland }
310*5c51f124SMoriah Waterland
311*5c51f124SMoriah Waterland /* scan dependency list for this item */
312*5c51f124SMoriah Waterland
313*5c51f124SMoriah Waterland for (j = 0;
314*5c51f124SMoriah Waterland DEPCKL[j].name != (char *)NULL; j++) {
315*5c51f124SMoriah Waterland len = strlen(DEPCKL[j].name);
316*5c51f124SMoriah Waterland
317*5c51f124SMoriah Waterland if (strncmp(line, DEPCKL[j].name,
318*5c51f124SMoriah Waterland len) == 0) {
319*5c51f124SMoriah Waterland break;
320*5c51f124SMoriah Waterland }
321*5c51f124SMoriah Waterland }
322*5c51f124SMoriah Waterland
323*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_SCAN, line, pkginst,
324*5c51f124SMoriah Waterland zoneName);
325*5c51f124SMoriah Waterland
326*5c51f124SMoriah Waterland /* ignore line if not found */
327*5c51f124SMoriah Waterland
328*5c51f124SMoriah Waterland if (DEPCKL[j].name == (char *)NULL) {
329*5c51f124SMoriah Waterland progerr(ERR_PRERVFY_UNKNOWN_LINE, line,
330*5c51f124SMoriah Waterland pkginst, zoneName);
331*5c51f124SMoriah Waterland continue;
332*5c51f124SMoriah Waterland }
333*5c51f124SMoriah Waterland
334*5c51f124SMoriah Waterland if ((DEPCKL[j].ignore_values != (char *)NULL) &&
335*5c51f124SMoriah Waterland (*(DEPCKL[j].ignore_values) != '\0') &&
336*5c51f124SMoriah Waterland (strchr(DEPCKL[j].ignore_values,
337*5c51f124SMoriah Waterland line[len]) != (char *)NULL)) {
338*5c51f124SMoriah Waterland continue;
339*5c51f124SMoriah Waterland }
340*5c51f124SMoriah Waterland /* found match - record this dependency issue */
341*5c51f124SMoriah Waterland
342*5c51f124SMoriah Waterland depchkRecordError(DEPCKL[j].record, pkginst,
343*5c51f124SMoriah Waterland zoneName, &line[len]);
344*5c51f124SMoriah Waterland }
345*5c51f124SMoriah Waterland
346*5c51f124SMoriah Waterland /* close preremove check data file */
347*5c51f124SMoriah Waterland
348*5c51f124SMoriah Waterland (void) fclose(fp);
349*5c51f124SMoriah Waterland }
350*5c51f124SMoriah Waterland }
351*5c51f124SMoriah Waterland
352*5c51f124SMoriah Waterland /*
353*5c51f124SMoriah Waterland * all dependency issues have been recorded; report results
354*5c51f124SMoriah Waterland */
355*5c51f124SMoriah Waterland
356*5c51f124SMoriah Waterland i = depchkReportErrors(DEPCKL);
357*5c51f124SMoriah Waterland
358*5c51f124SMoriah Waterland /* restore "npkgs" */
359*5c51f124SMoriah Waterland
360*5c51f124SMoriah Waterland npkgs = savenpkgs;
361*5c51f124SMoriah Waterland
362*5c51f124SMoriah Waterland /* return continue/dont dontinue results */
363*5c51f124SMoriah Waterland
364*5c51f124SMoriah Waterland return (i);
365*5c51f124SMoriah Waterland }
366*5c51f124SMoriah Waterland
367*5c51f124SMoriah Waterland /*
368*5c51f124SMoriah Waterland * Name: getyorn
369*5c51f124SMoriah Waterland * Description: Deliver dependency check reason; ask question; return response
370*5c51f124SMoriah Waterland * Arguments: a_msg - pointer to string representing the message to output
371*5c51f124SMoriah Waterland * such as 'The package <..> contains <...>'
372*5c51f124SMoriah Waterland * a_pkg - pointer to string representing the package for which
373*5c51f124SMoriah Waterland * the question is being asked
374*5c51f124SMoriah Waterland * a_nocheck - should the message be output?
375*5c51f124SMoriah Waterland * == 0 - do not output the message
376*5c51f124SMoriah Waterland * != 0 - output the message
377*5c51f124SMoriah Waterland * a_quit - should the question NOT be asked?
378*5c51f124SMoriah Waterland * == 0 - ask the question
379*5c51f124SMoriah Waterland * != 0 - do not ask the question - return "no"
380*5c51f124SMoriah Waterland * a_helpMsg - pointer to string representing help message to be
381*5c51f124SMoriah Waterland * made available if the question is asked
382*5c51f124SMoriah Waterland * == NULL - no help message is available
383*5c51f124SMoriah Waterland * a_adminMsg - pointer to string representing the dependency check
384*5c51f124SMoriah Waterland * failure 'reason' - such as "Privilege checking failed."
385*5c51f124SMoriah Waterland * == NULL - no failure reason is available
386*5c51f124SMoriah Waterland * Returns: int - results of question/response actions
387*5c51f124SMoriah Waterland * 0 - success
388*5c51f124SMoriah Waterland * 1 - end of file
389*5c51f124SMoriah Waterland * 2 - undefined error
390*5c51f124SMoriah Waterland * 3 - answer was not "y"/was "q"
391*5c51f124SMoriah Waterland * 4 - quit action taken
392*5c51f124SMoriah Waterland * 5 - interactive mode required
393*5c51f124SMoriah Waterland */
394*5c51f124SMoriah Waterland
395*5c51f124SMoriah Waterland static int
getyorn(char * a_msg,char * a_pkg,int a_nocheck,int a_quit,char * a_helpMsg,char * a_adminMsg)396*5c51f124SMoriah Waterland getyorn(char *a_msg, char *a_pkg, int a_nocheck, int a_quit,
397*5c51f124SMoriah Waterland char *a_helpMsg, char *a_adminMsg)
398*5c51f124SMoriah Waterland {
399*5c51f124SMoriah Waterland char ans[MAX_INPUT];
400*5c51f124SMoriah Waterland char ask_cont[MSG_MAX];
401*5c51f124SMoriah Waterland int n;
402*5c51f124SMoriah Waterland int saveCkquit;
403*5c51f124SMoriah Waterland
404*5c51f124SMoriah Waterland /*
405*5c51f124SMoriah Waterland * entry assertions
406*5c51f124SMoriah Waterland */
407*5c51f124SMoriah Waterland
408*5c51f124SMoriah Waterland assert(a_pkg != (char *)NULL);
409*5c51f124SMoriah Waterland assert(*a_pkg != '\0');
410*5c51f124SMoriah Waterland
411*5c51f124SMoriah Waterland /*
412*5c51f124SMoriah Waterland * entry debugging info
413*5c51f124SMoriah Waterland */
414*5c51f124SMoriah Waterland
415*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_ARGS, a_pkg, a_nocheck, a_quit, a_msg,
416*5c51f124SMoriah Waterland a_adminMsg ? a_adminMsg : "");
417*5c51f124SMoriah Waterland
418*5c51f124SMoriah Waterland /* return success (0) if "nocheck" is non-zero */
419*5c51f124SMoriah Waterland
420*5c51f124SMoriah Waterland if (a_nocheck != 0) {
421*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_NOCHECK, a_pkg);
422*5c51f124SMoriah Waterland return (0);
423*5c51f124SMoriah Waterland }
424*5c51f124SMoriah Waterland
425*5c51f124SMoriah Waterland /* output reason for this particular failure */
426*5c51f124SMoriah Waterland
427*5c51f124SMoriah Waterland if ((a_msg != (char *)NULL) && (*a_msg != '\0')) {
428*5c51f124SMoriah Waterland ptext(stderr, "%s", a_msg);
429*5c51f124SMoriah Waterland }
430*5c51f124SMoriah Waterland
431*5c51f124SMoriah Waterland /* return "4 (administration)" if "quit" is non-zero */
432*5c51f124SMoriah Waterland
433*5c51f124SMoriah Waterland if (a_quit != 0) {
434*5c51f124SMoriah Waterland /* output failure "admin reason" if available */
435*5c51f124SMoriah Waterland if ((a_adminMsg != (char *)NULL) && (*a_adminMsg != '\0')) {
436*5c51f124SMoriah Waterland ptext(stderr, a_adminMsg);
437*5c51f124SMoriah Waterland }
438*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_QUIT, a_pkg);
439*5c51f124SMoriah Waterland return (4);
440*5c51f124SMoriah Waterland }
441*5c51f124SMoriah Waterland
442*5c51f124SMoriah Waterland /* return "5 (administration interaction required)" if -n */
443*5c51f124SMoriah Waterland
444*5c51f124SMoriah Waterland if (echoGetFlag() == B_FALSE) {
445*5c51f124SMoriah Waterland ptext(stderr, MSG_PRERVFY_GETYORN_SUSP, a_pkg);
446*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_QUIT_USER, a_pkg);
447*5c51f124SMoriah Waterland return (5);
448*5c51f124SMoriah Waterland }
449*5c51f124SMoriah Waterland
450*5c51f124SMoriah Waterland /* prepare question to ask "continue with removal of pkg <xxx>?" */
451*5c51f124SMoriah Waterland
452*5c51f124SMoriah Waterland (void) snprintf(ask_cont, sizeof (ask_cont), gettext(ASK_PKGRMCHK_CONT),
453*5c51f124SMoriah Waterland a_pkg);
454*5c51f124SMoriah Waterland
455*5c51f124SMoriah Waterland /* ask question */
456*5c51f124SMoriah Waterland
457*5c51f124SMoriah Waterland saveCkquit = ckquit;
458*5c51f124SMoriah Waterland ckquit = 0;
459*5c51f124SMoriah Waterland
460*5c51f124SMoriah Waterland n = ckyorn(ans, NULL, NULL, a_helpMsg, ask_cont);
461*5c51f124SMoriah Waterland
462*5c51f124SMoriah Waterland ckquit = saveCkquit;
463*5c51f124SMoriah Waterland
464*5c51f124SMoriah Waterland if (n != 0) {
465*5c51f124SMoriah Waterland ptext(stderr, MSG_PRERVFY_GETYORN_TERM, a_pkg);
466*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_CKYORN, a_pkg, n);
467*5c51f124SMoriah Waterland return (n);
468*5c51f124SMoriah Waterland }
469*5c51f124SMoriah Waterland
470*5c51f124SMoriah Waterland /* return "3 (interruption) if not "y" or "Y" */
471*5c51f124SMoriah Waterland
472*5c51f124SMoriah Waterland if (strchr("yY", *ans) == NULL) {
473*5c51f124SMoriah Waterland ptext(stderr, MSG_PRERVFY_GETYORN_TERM_USER, a_pkg);
474*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_NOT_Y, a_pkg, ans);
475*5c51f124SMoriah Waterland return (3);
476*5c51f124SMoriah Waterland }
477*5c51f124SMoriah Waterland
478*5c51f124SMoriah Waterland /* return "0 - success" */
479*5c51f124SMoriah Waterland
480*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_GETYORN_SUCCESS, a_pkg);
481*5c51f124SMoriah Waterland
482*5c51f124SMoriah Waterland return (0);
483*5c51f124SMoriah Waterland }
484*5c51f124SMoriah Waterland
485*5c51f124SMoriah Waterland /*
486*5c51f124SMoriah Waterland * Trigger: dependsonme=<<package>>
487*5c51f124SMoriah Waterland * Sequence: - one or more: dependsonme=<<package>>
488*5c51f124SMoriah Waterland * - one: rckdepend=<<n>>
489*5c51f124SMoriah Waterland * Actions: Output message if "rdepend!=nocheck"
490*5c51f124SMoriah Waterland * Return 0
491*5c51f124SMoriah Waterland * Terminate when 'rckdepend' processed
492*5c51f124SMoriah Waterland */
493*5c51f124SMoriah Waterland
494*5c51f124SMoriah Waterland static int
rckdepsonme(char * a_msg,char * a_pkg)495*5c51f124SMoriah Waterland rckdepsonme(char *a_msg, char *a_pkg)
496*5c51f124SMoriah Waterland {
497*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_RCKDEPSONME, a_pkg, a_msg);
498*5c51f124SMoriah Waterland
499*5c51f124SMoriah Waterland if (!(ADM(rdepend, "nocheck"))) {
500*5c51f124SMoriah Waterland ptext(stderr, "%s", a_msg);
501*5c51f124SMoriah Waterland }
502*5c51f124SMoriah Waterland
503*5c51f124SMoriah Waterland return (0);
504*5c51f124SMoriah Waterland }
505*5c51f124SMoriah Waterland
506*5c51f124SMoriah Waterland /*
507*5c51f124SMoriah Waterland * Trigger: prerequisite-incomplete=<<package>>
508*5c51f124SMoriah Waterland * Sequence: - one or more: prerequisite-incomplete=<<package>>
509*5c51f124SMoriah Waterland * - one: rckdepend=<<n>>
510*5c51f124SMoriah Waterland * Actions: Output message if "rdepend!=nocheck"
511*5c51f124SMoriah Waterland * Return 0
512*5c51f124SMoriah Waterland * Terminate when 'rckdepend' processed
513*5c51f124SMoriah Waterland */
514*5c51f124SMoriah Waterland
515*5c51f124SMoriah Waterland static int
rckprenci(char * a_msg,char * a_pkg)516*5c51f124SMoriah Waterland rckprenci(char *a_msg, char *a_pkg)
517*5c51f124SMoriah Waterland {
518*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_RCKPRENCI, a_pkg, a_msg);
519*5c51f124SMoriah Waterland
520*5c51f124SMoriah Waterland if (!(ADM(rdepend, "nocheck"))) {
521*5c51f124SMoriah Waterland ptext(stderr, "%s", a_msg);
522*5c51f124SMoriah Waterland }
523*5c51f124SMoriah Waterland
524*5c51f124SMoriah Waterland return (0);
525*5c51f124SMoriah Waterland }
526*5c51f124SMoriah Waterland
527*5c51f124SMoriah Waterland /*
528*5c51f124SMoriah Waterland * Trigger: prerequisite-installed=<<package>>
529*5c51f124SMoriah Waterland * Sequence: - one or more: prerequisite-installed=<<package>>
530*5c51f124SMoriah Waterland * - one: rckdepend=<<n>>
531*5c51f124SMoriah Waterland * Actions: Output message if "rdepend!=nocheck"
532*5c51f124SMoriah Waterland * Return 0
533*5c51f124SMoriah Waterland * Terminate when 'rckdepend' processed
534*5c51f124SMoriah Waterland */
535*5c51f124SMoriah Waterland
536*5c51f124SMoriah Waterland static int
rckprereq(char * a_msg,char * a_pkg)537*5c51f124SMoriah Waterland rckprereq(char *a_msg, char *a_pkg)
538*5c51f124SMoriah Waterland {
539*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_RCKPREREQ, a_pkg, a_msg);
540*5c51f124SMoriah Waterland
541*5c51f124SMoriah Waterland if (!(ADM(rdepend, "nocheck"))) {
542*5c51f124SMoriah Waterland ptext(stderr, "%s", a_msg);
543*5c51f124SMoriah Waterland }
544*5c51f124SMoriah Waterland
545*5c51f124SMoriah Waterland return (0);
546*5c51f124SMoriah Waterland }
547*5c51f124SMoriah Waterland
548*5c51f124SMoriah Waterland /*
549*5c51f124SMoriah Waterland * Return value: int
550*5c51f124SMoriah Waterland * 0 - success
551*5c51f124SMoriah Waterland * 1 - end of file
552*5c51f124SMoriah Waterland * 2 - undefined error
553*5c51f124SMoriah Waterland * 3 - answer was not "y"/was "q"
554*5c51f124SMoriah Waterland * 4 - quit action taken
555*5c51f124SMoriah Waterland * 5 - interactive mode required
556*5c51f124SMoriah Waterland * 99 - fatal error
557*5c51f124SMoriah Waterland */
558*5c51f124SMoriah Waterland
559*5c51f124SMoriah Waterland static int
rckrunlevel(char * a_msg,char * a_pkg)560*5c51f124SMoriah Waterland rckrunlevel(char *a_msg, char *a_pkg)
561*5c51f124SMoriah Waterland {
562*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_RCKRUNLEVEL, a_pkg, a_msg);
563*5c51f124SMoriah Waterland /*
564*5c51f124SMoriah Waterland * For now, we are ignoring runlevel removal issues within
565*5c51f124SMoriah Waterland * non-global zones. This is questionable, but the RSTATES
566*5c51f124SMoriah Waterland * feature is rarely used and known uses within Solaris are
567*5c51f124SMoriah Waterland * effectively no-ops as of this time
568*5c51f124SMoriah Waterland */
569*5c51f124SMoriah Waterland return (0);
570*5c51f124SMoriah Waterland }
571*5c51f124SMoriah Waterland
572*5c51f124SMoriah Waterland /*
573*5c51f124SMoriah Waterland * Trigger: rckdepend=<<n>>
574*5c51f124SMoriah Waterland * Sequence: - one or more of:
575*5c51f124SMoriah Waterland * -- incompat=<<package>>
576*5c51f124SMoriah Waterland * -- prerequisite-incomplete=<<package>>
577*5c51f124SMoriah Waterland * -- prerequisite-installed=<<package>>
578*5c51f124SMoriah Waterland * -- dependson=<<package>>
579*5c51f124SMoriah Waterland * -- dependsonme=<<package>>
580*5c51f124SMoriah Waterland * - one: ckpdepend=<<n>>
581*5c51f124SMoriah Waterland * Actions: process according to settings
582*5c51f124SMoriah Waterland * Return value: int
583*5c51f124SMoriah Waterland * 0 - success
584*5c51f124SMoriah Waterland * 1 - end of file
585*5c51f124SMoriah Waterland * 2 - undefined error
586*5c51f124SMoriah Waterland * 3 - answer was not "y"/was "q"
587*5c51f124SMoriah Waterland * 4 - quit action taken
588*5c51f124SMoriah Waterland * 5 - interactive mode required
589*5c51f124SMoriah Waterland */
590*5c51f124SMoriah Waterland
591*5c51f124SMoriah Waterland static int
rckdepend(char * a_msg,char * a_pkg)592*5c51f124SMoriah Waterland rckdepend(char *a_msg, char *a_pkg)
593*5c51f124SMoriah Waterland {
594*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_RCKDEPEND, a_pkg, a_msg);
595*5c51f124SMoriah Waterland
596*5c51f124SMoriah Waterland return (getyorn(a_msg, a_pkg, ADM(rdepend, "nocheck"),
597*5c51f124SMoriah Waterland ADM(rdepend, "quit"), HLP_PKGRMCHK_DEPEND,
598*5c51f124SMoriah Waterland ERR_PKGRMCHK_DEPFAILED));
599*5c51f124SMoriah Waterland }
600*5c51f124SMoriah Waterland
601*5c51f124SMoriah Waterland /*
602*5c51f124SMoriah Waterland * Trigger: rckpriv=<<n>>
603*5c51f124SMoriah Waterland * Sequence: - one: rckpriv=<<n>>
604*5c51f124SMoriah Waterland * Actions: process according to settings
605*5c51f124SMoriah Waterland * Return value: int
606*5c51f124SMoriah Waterland * 0 - success
607*5c51f124SMoriah Waterland * 1 - end of file
608*5c51f124SMoriah Waterland * 2 - undefined error
609*5c51f124SMoriah Waterland * 3 - answer was not "y"/was "q"
610*5c51f124SMoriah Waterland * 4 - quit action taken
611*5c51f124SMoriah Waterland * 5 - interactive mode required
612*5c51f124SMoriah Waterland */
613*5c51f124SMoriah Waterland
614*5c51f124SMoriah Waterland static int
rckpriv(char * a_msg,char * a_pkg)615*5c51f124SMoriah Waterland rckpriv(char *a_msg, char *a_pkg)
616*5c51f124SMoriah Waterland {
617*5c51f124SMoriah Waterland echoDebug(DBG_PRERVFY_RCKPRIV, a_pkg, a_msg);
618*5c51f124SMoriah Waterland
619*5c51f124SMoriah Waterland return (getyorn(a_msg, a_pkg, ADM(action, "nocheck"),
620*5c51f124SMoriah Waterland ADM(action, "quit"), HLP_PKGRMCHK_PRIV,
621*5c51f124SMoriah Waterland ERR_PKGRMCHK_PRIVFAILED));
622*5c51f124SMoriah Waterland }
623