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 2004 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 * System includes
30*5c51f124SMoriah Waterland */
31*5c51f124SMoriah Waterland
32*5c51f124SMoriah Waterland #include <stdio.h>
33*5c51f124SMoriah Waterland #include <limits.h>
34*5c51f124SMoriah Waterland #include <string.h>
35*5c51f124SMoriah Waterland #include <stdlib.h>
36*5c51f124SMoriah Waterland #include <unistd.h>
37*5c51f124SMoriah Waterland #include <errno.h>
38*5c51f124SMoriah Waterland #include <sys/types.h>
39*5c51f124SMoriah Waterland #include <locale.h>
40*5c51f124SMoriah Waterland #include <libintl.h>
41*5c51f124SMoriah Waterland #include <assert.h>
42*5c51f124SMoriah Waterland
43*5c51f124SMoriah Waterland /*
44*5c51f124SMoriah Waterland * local pkg command library includes
45*5c51f124SMoriah Waterland */
46*5c51f124SMoriah Waterland
47*5c51f124SMoriah Waterland #include "libinst.h"
48*5c51f124SMoriah Waterland #include "messages.h"
49*5c51f124SMoriah Waterland
50*5c51f124SMoriah Waterland /*
51*5c51f124SMoriah Waterland * forward declarations
52*5c51f124SMoriah Waterland */
53*5c51f124SMoriah Waterland
54*5c51f124SMoriah Waterland static int
55*5c51f124SMoriah Waterland collectError(int *r_numZones, char **r_zoneNames, char *a_packageName,
56*5c51f124SMoriah Waterland depckl_t *a_dck, int a_depIndex, depckErrorRecord_t *a_eir,
57*5c51f124SMoriah Waterland int a_errIndex);
58*5c51f124SMoriah Waterland
59*5c51f124SMoriah Waterland /*
60*5c51f124SMoriah Waterland * *****************************************************************************
61*5c51f124SMoriah Waterland * global external (public) functions
62*5c51f124SMoriah Waterland * *****************************************************************************
63*5c51f124SMoriah Waterland */
64*5c51f124SMoriah Waterland
65*5c51f124SMoriah Waterland int
depchkReportErrors(depckl_t * a_dck)66*5c51f124SMoriah Waterland depchkReportErrors(depckl_t *a_dck)
67*5c51f124SMoriah Waterland {
68*5c51f124SMoriah Waterland char *packageName;
69*5c51f124SMoriah Waterland char *zonenames;
70*5c51f124SMoriah Waterland char msgbuf[4096];
71*5c51f124SMoriah Waterland int err;
72*5c51f124SMoriah Waterland int i;
73*5c51f124SMoriah Waterland int numzones = 0;
74*5c51f124SMoriah Waterland
75*5c51f124SMoriah Waterland /* entry assertions */
76*5c51f124SMoriah Waterland
77*5c51f124SMoriah Waterland assert(a_dck != (depckl_t *)NULL);
78*5c51f124SMoriah Waterland
79*5c51f124SMoriah Waterland /* entry debugging info */
80*5c51f124SMoriah Waterland
81*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_ENTRY);
82*5c51f124SMoriah Waterland
83*5c51f124SMoriah Waterland zonenames = (char *)NULL;
84*5c51f124SMoriah Waterland
85*5c51f124SMoriah Waterland /* go through dependency table, collect, collapse, report errors */
86*5c51f124SMoriah Waterland
87*5c51f124SMoriah Waterland for (i = 0; a_dck[i].name != (char *)NULL; i++) {
88*5c51f124SMoriah Waterland int j;
89*5c51f124SMoriah Waterland depckError_t *erc;
90*5c51f124SMoriah Waterland
91*5c51f124SMoriah Waterland if (zonenames != (char *)NULL) {
92*5c51f124SMoriah Waterland free(zonenames);
93*5c51f124SMoriah Waterland zonenames = (char *)NULL;
94*5c51f124SMoriah Waterland }
95*5c51f124SMoriah Waterland
96*5c51f124SMoriah Waterland erc = a_dck[i].record;
97*5c51f124SMoriah Waterland if (erc->er_numEntries == 0) {
98*5c51f124SMoriah Waterland continue;
99*5c51f124SMoriah Waterland }
100*5c51f124SMoriah Waterland
101*5c51f124SMoriah Waterland for (j = 0; j < erc->er_numEntries; j++) {
102*5c51f124SMoriah Waterland int k;
103*5c51f124SMoriah Waterland depckErrorRecord_t *eir;
104*5c51f124SMoriah Waterland
105*5c51f124SMoriah Waterland if (zonenames != (char *)NULL) {
106*5c51f124SMoriah Waterland free(zonenames);
107*5c51f124SMoriah Waterland zonenames = (char *)NULL;
108*5c51f124SMoriah Waterland }
109*5c51f124SMoriah Waterland
110*5c51f124SMoriah Waterland eir = &erc->er_theEntries[j];
111*5c51f124SMoriah Waterland packageName = eir->ier_packageName;
112*5c51f124SMoriah Waterland for (k = 0; k < eir->ier_numZones; k++) {
113*5c51f124SMoriah Waterland int err;
114*5c51f124SMoriah Waterland
115*5c51f124SMoriah Waterland err = collectError(&numzones, &zonenames,
116*5c51f124SMoriah Waterland packageName, a_dck, i, eir, k);
117*5c51f124SMoriah Waterland if (err != 0) {
118*5c51f124SMoriah Waterland if (zonenames != (char *)NULL) {
119*5c51f124SMoriah Waterland free(zonenames);
120*5c51f124SMoriah Waterland zonenames = (char *)NULL;
121*5c51f124SMoriah Waterland }
122*5c51f124SMoriah Waterland return (err);
123*5c51f124SMoriah Waterland }
124*5c51f124SMoriah Waterland }
125*5c51f124SMoriah Waterland
126*5c51f124SMoriah Waterland if (a_dck[i].ignore_values == (char *)NULL) {
127*5c51f124SMoriah Waterland continue;
128*5c51f124SMoriah Waterland }
129*5c51f124SMoriah Waterland
130*5c51f124SMoriah Waterland if (a_dck[i].err_msg == (char **)NULL) {
131*5c51f124SMoriah Waterland (void) snprintf(msgbuf, sizeof (msgbuf),
132*5c51f124SMoriah Waterland ERR_DEPENDENCY_IGNORED, a_dck[i].name,
133*5c51f124SMoriah Waterland packageName,
134*5c51f124SMoriah Waterland numzones == 1 ? "zone" : "zones",
135*5c51f124SMoriah Waterland zonenames ? zonenames : "?");
136*5c51f124SMoriah Waterland } else {
137*5c51f124SMoriah Waterland /* LINTED variable format specifier to ... */
138*5c51f124SMoriah Waterland (void) snprintf(msgbuf, sizeof (msgbuf),
139*5c51f124SMoriah Waterland *a_dck[i].err_msg, "package",
140*5c51f124SMoriah Waterland packageName,
141*5c51f124SMoriah Waterland numzones == 1 ? "zone" : "zones",
142*5c51f124SMoriah Waterland zonenames ? zonenames : "??");
143*5c51f124SMoriah Waterland }
144*5c51f124SMoriah Waterland
145*5c51f124SMoriah Waterland if (a_dck[i].depcklFunc != NULL) {
146*5c51f124SMoriah Waterland /* call check function */
147*5c51f124SMoriah Waterland err = (a_dck[i].depcklFunc)(msgbuf,
148*5c51f124SMoriah Waterland packageName);
149*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_REPORT_ERROR,
150*5c51f124SMoriah Waterland a_dck[i].ignore_values, err,
151*5c51f124SMoriah Waterland packageName, msgbuf);
152*5c51f124SMoriah Waterland if (err != 0) {
153*5c51f124SMoriah Waterland if (zonenames != (char *)NULL) {
154*5c51f124SMoriah Waterland free(zonenames);
155*5c51f124SMoriah Waterland zonenames = (char *)NULL;
156*5c51f124SMoriah Waterland }
157*5c51f124SMoriah Waterland return (err);
158*5c51f124SMoriah Waterland }
159*5c51f124SMoriah Waterland } else {
160*5c51f124SMoriah Waterland /* no check function - just report message */
161*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_IGNORE_ERROR,
162*5c51f124SMoriah Waterland a_dck[i].ignore_values, packageName,
163*5c51f124SMoriah Waterland msgbuf);
164*5c51f124SMoriah Waterland ptext(stderr, "\\n%s", msgbuf);
165*5c51f124SMoriah Waterland }
166*5c51f124SMoriah Waterland }
167*5c51f124SMoriah Waterland }
168*5c51f124SMoriah Waterland
169*5c51f124SMoriah Waterland if (zonenames != (char *)NULL) {
170*5c51f124SMoriah Waterland free(zonenames);
171*5c51f124SMoriah Waterland zonenames = (char *)NULL;
172*5c51f124SMoriah Waterland }
173*5c51f124SMoriah Waterland
174*5c51f124SMoriah Waterland return (0);
175*5c51f124SMoriah Waterland }
176*5c51f124SMoriah Waterland
177*5c51f124SMoriah Waterland void
depchkRecordError(depckError_t * a_erc,char * a_pkginst,char * a_zoneName,char * a_value)178*5c51f124SMoriah Waterland depchkRecordError(depckError_t *a_erc, char *a_pkginst,
179*5c51f124SMoriah Waterland char *a_zoneName, char *a_value)
180*5c51f124SMoriah Waterland {
181*5c51f124SMoriah Waterland depckErrorRecord_t *erc;
182*5c51f124SMoriah Waterland int i;
183*5c51f124SMoriah Waterland
184*5c51f124SMoriah Waterland /*
185*5c51f124SMoriah Waterland * create new error record and entry if first entry
186*5c51f124SMoriah Waterland * record will look like this:
187*5c51f124SMoriah Waterland * err->er_#entry=1
188*5c51f124SMoriah Waterland * err->entry[0]->record->ier_numZones=1
189*5c51f124SMoriah Waterland * err->entry[0]->record->ier_packageName=a_pkginst
190*5c51f124SMoriah Waterland * err->entry[0]->record->ier_zones[0]=a_zoneName
191*5c51f124SMoriah Waterland * err->entry[0]->record->ier_values[0]=a_value
192*5c51f124SMoriah Waterland */
193*5c51f124SMoriah Waterland
194*5c51f124SMoriah Waterland if (a_erc->er_numEntries == 0) {
195*5c51f124SMoriah Waterland depckErrorRecord_t *eir;
196*5c51f124SMoriah Waterland
197*5c51f124SMoriah Waterland eir = (depckErrorRecord_t *)calloc(1,
198*5c51f124SMoriah Waterland sizeof (depckErrorRecord_t));
199*5c51f124SMoriah Waterland eir->ier_packageName = strdup(a_pkginst);
200*5c51f124SMoriah Waterland eir->ier_numZones = 1;
201*5c51f124SMoriah Waterland eir->ier_zones = (char **)calloc(1, sizeof (char **));
202*5c51f124SMoriah Waterland (eir->ier_zones)[eir->ier_numZones-1] = strdup(a_zoneName);
203*5c51f124SMoriah Waterland eir->ier_values = (char **)calloc(1, sizeof (char *));
204*5c51f124SMoriah Waterland (eir->ier_values)[eir->ier_numZones-1] = strdup(a_value);
205*5c51f124SMoriah Waterland
206*5c51f124SMoriah Waterland a_erc->er_numEntries = 1;
207*5c51f124SMoriah Waterland a_erc->er_theEntries = eir;
208*5c51f124SMoriah Waterland
209*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_RECORD_ERROR, (long)a_erc, a_pkginst,
210*5c51f124SMoriah Waterland a_zoneName, a_value);
211*5c51f124SMoriah Waterland
212*5c51f124SMoriah Waterland return;
213*5c51f124SMoriah Waterland }
214*5c51f124SMoriah Waterland
215*5c51f124SMoriah Waterland /* see if this package already has an entry if so add zone to list */
216*5c51f124SMoriah Waterland
217*5c51f124SMoriah Waterland for (i = 0; i < a_erc->er_numEntries; i++) {
218*5c51f124SMoriah Waterland erc = &a_erc->er_theEntries[i];
219*5c51f124SMoriah Waterland
220*5c51f124SMoriah Waterland if (strcmp(erc->ier_packageName, a_pkginst) != 0) {
221*5c51f124SMoriah Waterland continue;
222*5c51f124SMoriah Waterland }
223*5c51f124SMoriah Waterland
224*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_RECORD_ZERROR, (long)a_erc, a_zoneName,
225*5c51f124SMoriah Waterland a_value, erc->ier_packageName, erc->ier_numZones,
226*5c51f124SMoriah Waterland erc->ier_zones[0]);
227*5c51f124SMoriah Waterland
228*5c51f124SMoriah Waterland /*
229*5c51f124SMoriah Waterland * this package already has an entry - add zone to
230*5c51f124SMoriah Waterland * existing package entry the modified records will
231*5c51f124SMoriah Waterland * look like this:
232*5c51f124SMoriah Waterland * err->er_#entry++;
233*5c51f124SMoriah Waterland * err->entry[0]->...
234*5c51f124SMoriah Waterland * err->entry[i]->
235*5c51f124SMoriah Waterland * -------------->record->
236*5c51f124SMoriah Waterland * ---------------------->ier_numZones++;
237*5c51f124SMoriah Waterland * ---------------------->ier_packageName=a_pkginst
238*5c51f124SMoriah Waterland * ---------------------->ier_zones[0]=...
239*5c51f124SMoriah Waterland * ---------------------->ier_zones[...]=...
240*5c51f124SMoriah Waterland * ---------------------->ier_zones[ier_numZones-1]=a_zoneName
241*5c51f124SMoriah Waterland * ---------------------->ier_values[0]=...
242*5c51f124SMoriah Waterland * ---------------------->ier_values[...]=...
243*5c51f124SMoriah Waterland * ---------------------->ier_values[ier_numZones-1]=a_value
244*5c51f124SMoriah Waterland * err->entry[i+1]->...
245*5c51f124SMoriah Waterland */
246*5c51f124SMoriah Waterland erc->ier_numZones++;
247*5c51f124SMoriah Waterland erc->ier_zones = (char **)realloc(erc->ier_zones,
248*5c51f124SMoriah Waterland sizeof (char **)*erc->ier_numZones);
249*5c51f124SMoriah Waterland (erc->ier_zones)[erc->ier_numZones-1] = strdup(a_zoneName);
250*5c51f124SMoriah Waterland erc->ier_values = (char **)realloc(erc->ier_values,
251*5c51f124SMoriah Waterland sizeof (char **)*erc->ier_numZones);
252*5c51f124SMoriah Waterland (erc->ier_values)[erc->ier_numZones-1] = strdup(a_value);
253*5c51f124SMoriah Waterland return;
254*5c51f124SMoriah Waterland }
255*5c51f124SMoriah Waterland
256*5c51f124SMoriah Waterland /*
257*5c51f124SMoriah Waterland * this packages does not have an entry - add new package
258*5c51f124SMoriah Waterland * entry for this zone the modified records will look like this:
259*5c51f124SMoriah Waterland * err->er_#entry++;
260*5c51f124SMoriah Waterland * err->entry[0]->record->ier_numZones=...
261*5c51f124SMoriah Waterland * err->entry[0]->record->ier_packageName=...
262*5c51f124SMoriah Waterland * err->entry[0]->record->ier_zones[0]=...
263*5c51f124SMoriah Waterland * err->entry[0]->record->ier_values[0]=...
264*5c51f124SMoriah Waterland * err->entry[er_#entry-1]->record->ier_numZones=1
265*5c51f124SMoriah Waterland * err->entry[er_#entry-1]->record->ier_packageName=a_pkginst
266*5c51f124SMoriah Waterland * err->entry[er_#entry-1]->record->ier_zones[0]=a_zoneName
267*5c51f124SMoriah Waterland * err->entry[er_#entry-1]->record->ier_values[0]=a_value
268*5c51f124SMoriah Waterland */
269*5c51f124SMoriah Waterland
270*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_RECORD_PERROR, (long)a_erc,
271*5c51f124SMoriah Waterland a_erc->er_numEntries, a_pkginst, a_zoneName, a_value);
272*5c51f124SMoriah Waterland
273*5c51f124SMoriah Waterland a_erc->er_numEntries++;
274*5c51f124SMoriah Waterland
275*5c51f124SMoriah Waterland a_erc->er_theEntries = realloc(a_erc->er_theEntries,
276*5c51f124SMoriah Waterland sizeof (depckErrorRecord_t)*a_erc->er_numEntries);
277*5c51f124SMoriah Waterland
278*5c51f124SMoriah Waterland erc = &a_erc->er_theEntries[a_erc->er_numEntries-1];
279*5c51f124SMoriah Waterland
280*5c51f124SMoriah Waterland erc->ier_packageName = strdup(a_pkginst);
281*5c51f124SMoriah Waterland erc->ier_numZones = 1;
282*5c51f124SMoriah Waterland erc->ier_zones = (char **)calloc(1, sizeof (char *));
283*5c51f124SMoriah Waterland (erc->ier_zones)[erc->ier_numZones-1] = strdup(a_zoneName);
284*5c51f124SMoriah Waterland erc->ier_values = (char **)calloc(1, sizeof (char *));
285*5c51f124SMoriah Waterland (erc->ier_values)[erc->ier_numZones-1] = strdup(a_value);
286*5c51f124SMoriah Waterland }
287*5c51f124SMoriah Waterland
288*5c51f124SMoriah Waterland /*
289*5c51f124SMoriah Waterland * *****************************************************************************
290*5c51f124SMoriah Waterland * static internal (private) functions
291*5c51f124SMoriah Waterland * *****************************************************************************
292*5c51f124SMoriah Waterland */
293*5c51f124SMoriah Waterland
294*5c51f124SMoriah Waterland static int
collectError(int * r_numZones,char ** r_zoneNames,char * a_packageName,depckl_t * a_dck,int a_depIndex,depckErrorRecord_t * a_eir,int a_errIndex)295*5c51f124SMoriah Waterland collectError(int *r_numZones, char **r_zoneNames, char *a_packageName,
296*5c51f124SMoriah Waterland depckl_t *a_dck, int a_depIndex, depckErrorRecord_t *a_eir,
297*5c51f124SMoriah Waterland int a_errIndex)
298*5c51f124SMoriah Waterland {
299*5c51f124SMoriah Waterland char msgbuf[4096];
300*5c51f124SMoriah Waterland char *zn = *r_zoneNames;
301*5c51f124SMoriah Waterland
302*5c51f124SMoriah Waterland if (a_dck[a_depIndex].ignore_values == (char *)NULL) {
303*5c51f124SMoriah Waterland if (a_dck[a_depIndex].err_msg == (char **)NULL) {
304*5c51f124SMoriah Waterland (void) snprintf(msgbuf, sizeof (msgbuf),
305*5c51f124SMoriah Waterland ERR_DEPENDENCY_REPORT, a_eir->ier_values[a_errIndex],
306*5c51f124SMoriah Waterland "package", a_packageName,
307*5c51f124SMoriah Waterland "zone", a_eir->ier_zones[a_errIndex]);
308*5c51f124SMoriah Waterland } else {
309*5c51f124SMoriah Waterland /* LINTED variable format specifier to snprintf(); */
310*5c51f124SMoriah Waterland (void) snprintf(msgbuf, sizeof (msgbuf),
311*5c51f124SMoriah Waterland *a_dck[a_depIndex].err_msg,
312*5c51f124SMoriah Waterland a_eir->ier_values[a_errIndex],
313*5c51f124SMoriah Waterland "package", a_packageName,
314*5c51f124SMoriah Waterland "zone", a_eir->ier_zones[a_errIndex]);
315*5c51f124SMoriah Waterland }
316*5c51f124SMoriah Waterland if (a_dck[a_depIndex].depcklFunc != NULL) {
317*5c51f124SMoriah Waterland int err;
318*5c51f124SMoriah Waterland
319*5c51f124SMoriah Waterland err = (a_dck[a_depIndex].depcklFunc)(msgbuf,
320*5c51f124SMoriah Waterland a_packageName);
321*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_COLLECT_ERROR, err, a_packageName,
322*5c51f124SMoriah Waterland msgbuf);
323*5c51f124SMoriah Waterland if (err != 0) {
324*5c51f124SMoriah Waterland return (err);
325*5c51f124SMoriah Waterland }
326*5c51f124SMoriah Waterland } else {
327*5c51f124SMoriah Waterland echoDebug(DBG_DEPCHK_COLLECT_IGNORE, a_packageName,
328*5c51f124SMoriah Waterland msgbuf);
329*5c51f124SMoriah Waterland ptext(stderr, "\\n%s", msgbuf);
330*5c51f124SMoriah Waterland }
331*5c51f124SMoriah Waterland return (0);
332*5c51f124SMoriah Waterland }
333*5c51f124SMoriah Waterland
334*5c51f124SMoriah Waterland *r_numZones = (*r_numZones)+1;
335*5c51f124SMoriah Waterland if (zn == (char *)NULL) {
336*5c51f124SMoriah Waterland zn = strdup(a_eir->ier_zones[a_errIndex]);
337*5c51f124SMoriah Waterland } else {
338*5c51f124SMoriah Waterland char *p;
339*5c51f124SMoriah Waterland int len = strlen(zn)+strlen(a_eir->ier_zones[a_errIndex])+3;
340*5c51f124SMoriah Waterland p = calloc(1, len);
341*5c51f124SMoriah Waterland (void) snprintf(p, len, "%s, %s", zn,
342*5c51f124SMoriah Waterland a_eir->ier_zones[a_errIndex]);
343*5c51f124SMoriah Waterland free(zn);
344*5c51f124SMoriah Waterland zn = p;
345*5c51f124SMoriah Waterland
346*5c51f124SMoriah Waterland }
347*5c51f124SMoriah Waterland *r_zoneNames = zn;
348*5c51f124SMoriah Waterland return (0);
349*5c51f124SMoriah Waterland }
350