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