xref: /titanic_51/usr/src/cmd/svr4pkg/libinst/depchk.c (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 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
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
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
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