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 <stdlib.h> 31*5c51f124SMoriah Waterland #include <unistd.h> 32*5c51f124SMoriah Waterland #include <string.h> 33*5c51f124SMoriah Waterland #include <fcntl.h> 34*5c51f124SMoriah Waterland #include <sys/types.h> 35*5c51f124SMoriah Waterland #include <sys/stat.h> 36*5c51f124SMoriah Waterland #include <signal.h> 37*5c51f124SMoriah Waterland #include <errno.h> 38*5c51f124SMoriah Waterland #include <assert.h> 39*5c51f124SMoriah Waterland #include <pkgdev.h> 40*5c51f124SMoriah Waterland #include <pkginfo.h> 41*5c51f124SMoriah Waterland #include <pkglocs.h> 42*5c51f124SMoriah Waterland #include <locale.h> 43*5c51f124SMoriah Waterland #include <libintl.h> 44*5c51f124SMoriah Waterland #include <instzones_api.h> 45*5c51f124SMoriah Waterland #include <pkglib.h> 46*5c51f124SMoriah Waterland #include <install.h> 47*5c51f124SMoriah Waterland #include <libinst.h> 48*5c51f124SMoriah Waterland #include <libadm.h> 49*5c51f124SMoriah Waterland #include <messages.h> 50*5c51f124SMoriah Waterland 51*5c51f124SMoriah Waterland /* commands to execute */ 52*5c51f124SMoriah Waterland 53*5c51f124SMoriah Waterland #define PKGINFO_CMD "/usr/bin/pkginfo" 54*5c51f124SMoriah Waterland 55*5c51f124SMoriah Waterland #define GLOBALZONE_ONLY_PACKAGE_FILE_PATH \ 56*5c51f124SMoriah Waterland "/var/sadm/install/gz-only-packages" 57*5c51f124SMoriah Waterland 58*5c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 59*5c51f124SMoriah Waterland #define TEXT_DOMAIN "SYS_TEST" 60*5c51f124SMoriah Waterland #endif 61*5c51f124SMoriah Waterland 62*5c51f124SMoriah Waterland /* 63*5c51f124SMoriah Waterland * forward declarations 64*5c51f124SMoriah Waterland */ 65*5c51f124SMoriah Waterland 66*5c51f124SMoriah Waterland static void _pkginfoInit(struct pkginfo *a_info); 67*5c51f124SMoriah Waterland static struct pkginfo *_pkginfoFactory(void); 68*5c51f124SMoriah Waterland static char **thisZonePackages; 69*5c51f124SMoriah Waterland static int numThisZonePackages; 70*5c51f124SMoriah Waterland 71*5c51f124SMoriah Waterland /* 72*5c51f124SMoriah Waterland * ***************************************************************************** 73*5c51f124SMoriah Waterland * global external (public) functions 74*5c51f124SMoriah Waterland * ***************************************************************************** 75*5c51f124SMoriah Waterland */ 76*5c51f124SMoriah Waterland 77*5c51f124SMoriah Waterland /* 78*5c51f124SMoriah Waterland * Name: pkginfoFree 79*5c51f124SMoriah Waterland * Description: free pkginfo structure returned from various functions 80*5c51f124SMoriah Waterland * Arguments: r_info - pointer to pointer to pkginfo structure to free 81*5c51f124SMoriah Waterland * Returns: void 82*5c51f124SMoriah Waterland */ 83*5c51f124SMoriah Waterland 84*5c51f124SMoriah Waterland void 85*5c51f124SMoriah Waterland pkginfoFree(struct pkginfo **r_info) 86*5c51f124SMoriah Waterland { 87*5c51f124SMoriah Waterland struct pkginfo *pinfo; 88*5c51f124SMoriah Waterland 89*5c51f124SMoriah Waterland /* entry assertions */ 90*5c51f124SMoriah Waterland 91*5c51f124SMoriah Waterland assert(r_info != (struct pkginfo **)NULL); 92*5c51f124SMoriah Waterland 93*5c51f124SMoriah Waterland /* localize reference to info structure to free */ 94*5c51f124SMoriah Waterland 95*5c51f124SMoriah Waterland pinfo = *r_info; 96*5c51f124SMoriah Waterland 97*5c51f124SMoriah Waterland /* reset callers handle to info structure */ 98*5c51f124SMoriah Waterland 99*5c51f124SMoriah Waterland *r_info = (struct pkginfo *)NULL; 100*5c51f124SMoriah Waterland 101*5c51f124SMoriah Waterland assert(pinfo != (struct pkginfo *)NULL); 102*5c51f124SMoriah Waterland 103*5c51f124SMoriah Waterland /* free up contents of the structure */ 104*5c51f124SMoriah Waterland 105*5c51f124SMoriah Waterland _pkginfoInit(pinfo); 106*5c51f124SMoriah Waterland 107*5c51f124SMoriah Waterland /* free up structure itself */ 108*5c51f124SMoriah Waterland 109*5c51f124SMoriah Waterland (void) free(pinfo); 110*5c51f124SMoriah Waterland } 111*5c51f124SMoriah Waterland 112*5c51f124SMoriah Waterland /* 113*5c51f124SMoriah Waterland * Name: pkginfoIsPkgInstalled 114*5c51f124SMoriah Waterland * Description: determine if specified package is installed, return pkginfo 115*5c51f124SMoriah Waterland * structure describing package if package is installed 116*5c51f124SMoriah Waterland * Arguments: r_pinfo - pointer to pointer to pkginfo structure 117*5c51f124SMoriah Waterland * If this pointer is NOT null: 118*5c51f124SMoriah Waterland * -On success, this handle is filled in with a pointer 119*5c51f124SMoriah Waterland * --to a newly allocated pkginfo structure describing 120*5c51f124SMoriah Waterland * --the package discovered 121*5c51f124SMoriah Waterland * -On failure, this handle is filled with NULL 122*5c51f124SMoriah Waterland * If this pointer is NULL: 123*5c51f124SMoriah Waterland * -no pkginfo structure is returned on success. 124*5c51f124SMoriah Waterland * a_pkgInst - package instance (name) to lookup 125*5c51f124SMoriah Waterland * Returns: boolean_t 126*5c51f124SMoriah Waterland * B_TRUE - package installed, pkginfo returned 127*5c51f124SMoriah Waterland * B_FALSE - package not installed, no pkginfo returned 128*5c51f124SMoriah Waterland * NOTE: This function returns the first instance of package that 129*5c51f124SMoriah Waterland * is installed - see pkginfo() function for details 130*5c51f124SMoriah Waterland * NOTE: Any pkginfo structure returned is placed in new storage for the 131*5c51f124SMoriah Waterland * calling function. The caller must use 'pkginfoFree' to dispose 132*5c51f124SMoriah Waterland * of the storage once the pkginfo structure is no longer needed. 133*5c51f124SMoriah Waterland */ 134*5c51f124SMoriah Waterland 135*5c51f124SMoriah Waterland boolean_t 136*5c51f124SMoriah Waterland pkginfoIsPkgInstalled(struct pkginfo **r_pinfo, char *a_pkgInst) 137*5c51f124SMoriah Waterland { 138*5c51f124SMoriah Waterland int r; 139*5c51f124SMoriah Waterland struct pkginfo *pinf; 140*5c51f124SMoriah Waterland 141*5c51f124SMoriah Waterland /* entry assertions */ 142*5c51f124SMoriah Waterland 143*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 144*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 145*5c51f124SMoriah Waterland 146*5c51f124SMoriah Waterland /* reset returned pkginfo structure handle */ 147*5c51f124SMoriah Waterland 148*5c51f124SMoriah Waterland if (r_pinfo != (struct pkginfo **)NULL) { 149*5c51f124SMoriah Waterland *r_pinfo = (struct pkginfo *)NULL; 150*5c51f124SMoriah Waterland } 151*5c51f124SMoriah Waterland 152*5c51f124SMoriah Waterland /* allocate a new pinfo structure for use in the call to pkginfo */ 153*5c51f124SMoriah Waterland 154*5c51f124SMoriah Waterland pinf = _pkginfoFactory(); 155*5c51f124SMoriah Waterland 156*5c51f124SMoriah Waterland /* lookup the specified package */ 157*5c51f124SMoriah Waterland 158*5c51f124SMoriah Waterland /* NOTE: required 'pkgdir' set to spool directory or NULL */ 159*5c51f124SMoriah Waterland r = pkginfo(pinf, a_pkgInst, NULL, NULL); 160*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, a_pkgInst, r); 161*5c51f124SMoriah Waterland 162*5c51f124SMoriah Waterland if (r_pinfo != (struct pkginfo **)NULL) { 163*5c51f124SMoriah Waterland *r_pinfo = pinf; 164*5c51f124SMoriah Waterland } else { 165*5c51f124SMoriah Waterland /* free pkginfo structure */ 166*5c51f124SMoriah Waterland pkginfoFree(&pinf); 167*5c51f124SMoriah Waterland } 168*5c51f124SMoriah Waterland 169*5c51f124SMoriah Waterland return (r == 0 ? B_TRUE : B_FALSE); 170*5c51f124SMoriah Waterland } 171*5c51f124SMoriah Waterland 172*5c51f124SMoriah Waterland /* 173*5c51f124SMoriah Waterland * Name: pkgOpenInGzOnlyFile 174*5c51f124SMoriah Waterland * Description: Open the global zone only package list file 175*5c51f124SMoriah Waterland * Arguments: a_rootPath - pointer to string representing the root path 176*5c51f124SMoriah Waterland * where the global zone only package list file is 177*5c51f124SMoriah Waterland * located - NULL is the same as "/" 178*5c51f124SMoriah Waterland * Returns: FILE * 179*5c51f124SMoriah Waterland * == NULL - failure - file not open 180*5c51f124SMoriah Waterland * != NULL - success - file pointer returned 181*5c51f124SMoriah Waterland * NOTE: This function will create the file if it does not exist. 182*5c51f124SMoriah Waterland */ 183*5c51f124SMoriah Waterland 184*5c51f124SMoriah Waterland FILE * 185*5c51f124SMoriah Waterland pkgOpenInGzOnlyFile(char *a_rootPath) 186*5c51f124SMoriah Waterland { 187*5c51f124SMoriah Waterland FILE *pkgingzonlyFP; 188*5c51f124SMoriah Waterland char pkgingzonlyPath[PATH_MAX]; 189*5c51f124SMoriah Waterland int len; 190*5c51f124SMoriah Waterland 191*5c51f124SMoriah Waterland /* normalize root path */ 192*5c51f124SMoriah Waterland 193*5c51f124SMoriah Waterland if (a_rootPath == (char *)NULL) { 194*5c51f124SMoriah Waterland a_rootPath = ""; 195*5c51f124SMoriah Waterland } 196*5c51f124SMoriah Waterland 197*5c51f124SMoriah Waterland /* generate path to glocal zone only list file */ 198*5c51f124SMoriah Waterland 199*5c51f124SMoriah Waterland len = snprintf(pkgingzonlyPath, sizeof (pkgingzonlyPath), "%s/%s", 200*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 201*5c51f124SMoriah Waterland if (len > sizeof (pkgingzonlyPath)) { 202*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 203*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 204*5c51f124SMoriah Waterland return ((FILE *)NULL); 205*5c51f124SMoriah Waterland } 206*5c51f124SMoriah Waterland 207*5c51f124SMoriah Waterland /* open global zone only list file */ 208*5c51f124SMoriah Waterland 209*5c51f124SMoriah Waterland pkgingzonlyFP = fopen(pkgingzonlyPath, "r+"); 210*5c51f124SMoriah Waterland if ((pkgingzonlyFP == (FILE *)NULL) && (errno == ENOENT)) { 211*5c51f124SMoriah Waterland pkgingzonlyFP = fopen(pkgingzonlyPath, "w+"); 212*5c51f124SMoriah Waterland } 213*5c51f124SMoriah Waterland 214*5c51f124SMoriah Waterland if ((pkgingzonlyFP == (FILE *)NULL) && (errno != ENOENT)) { 215*5c51f124SMoriah Waterland progerr(ERR_PKGOPS_OPEN_GZONLY, pkgingzonlyPath, 216*5c51f124SMoriah Waterland strerror(errno)); 217*5c51f124SMoriah Waterland return ((FILE *)NULL); 218*5c51f124SMoriah Waterland } 219*5c51f124SMoriah Waterland 220*5c51f124SMoriah Waterland /* success - return FILE pointer open on global zone only list file */ 221*5c51f124SMoriah Waterland 222*5c51f124SMoriah Waterland return (pkgingzonlyFP); 223*5c51f124SMoriah Waterland } 224*5c51f124SMoriah Waterland 225*5c51f124SMoriah Waterland /* 226*5c51f124SMoriah Waterland * Name: pkgIsPkgInGzOnly 227*5c51f124SMoriah Waterland * Description: determine if package is recorded as "in global zone only" 228*5c51f124SMoriah Waterland * by opening the appropriate files and searching for the 229*5c51f124SMoriah Waterland * specified package 230*5c51f124SMoriah Waterland * Arguments: a_rootPath - pointer to string representing the root path 231*5c51f124SMoriah Waterland * where the global zone only package list file is 232*5c51f124SMoriah Waterland * located - NULL is the same as "/" 233*5c51f124SMoriah Waterland * a_pkgInst - pointer to string representing the package instance 234*5c51f124SMoriah Waterland * (name) of the package to lookup 235*5c51f124SMoriah Waterland * Returns: boolean_t 236*5c51f124SMoriah Waterland * B_TRUE - package is recorded as "in global zone only" 237*5c51f124SMoriah Waterland * B_FALSE - package is NOT recorded as "in gz only" 238*5c51f124SMoriah Waterland * NOTE: This function will create the file if it does not exist. 239*5c51f124SMoriah Waterland */ 240*5c51f124SMoriah Waterland 241*5c51f124SMoriah Waterland boolean_t 242*5c51f124SMoriah Waterland pkgIsPkgInGzOnly(char *a_rootPath, char *a_pkgInst) 243*5c51f124SMoriah Waterland { 244*5c51f124SMoriah Waterland FILE *fp; 245*5c51f124SMoriah Waterland boolean_t in_gz_only; 246*5c51f124SMoriah Waterland 247*5c51f124SMoriah Waterland /* normalize root path */ 248*5c51f124SMoriah Waterland 249*5c51f124SMoriah Waterland if (a_rootPath == (char *)NULL) { 250*5c51f124SMoriah Waterland a_rootPath = ""; 251*5c51f124SMoriah Waterland } 252*5c51f124SMoriah Waterland 253*5c51f124SMoriah Waterland /* open the global zone only package list file */ 254*5c51f124SMoriah Waterland 255*5c51f124SMoriah Waterland fp = pkgOpenInGzOnlyFile(a_rootPath); 256*5c51f124SMoriah Waterland if (fp == (FILE *)NULL) { 257*5c51f124SMoriah Waterland echoDebug(ERR_PKGOPS_CANNOT_OPEN_GZONLY, 258*5c51f124SMoriah Waterland a_rootPath ? a_rootPath : "/"); 259*5c51f124SMoriah Waterland return (B_FALSE); 260*5c51f124SMoriah Waterland } 261*5c51f124SMoriah Waterland 262*5c51f124SMoriah Waterland /* is the package recorded as "in global zone only" ? */ 263*5c51f124SMoriah Waterland 264*5c51f124SMoriah Waterland in_gz_only = pkgIsPkgInGzOnlyFP(fp, a_pkgInst); 265*5c51f124SMoriah Waterland 266*5c51f124SMoriah Waterland /* close the global zone only package list file */ 267*5c51f124SMoriah Waterland 268*5c51f124SMoriah Waterland (void) fclose(fp); 269*5c51f124SMoriah Waterland 270*5c51f124SMoriah Waterland /* return results */ 271*5c51f124SMoriah Waterland 272*5c51f124SMoriah Waterland return (in_gz_only); 273*5c51f124SMoriah Waterland } 274*5c51f124SMoriah Waterland 275*5c51f124SMoriah Waterland /* 276*5c51f124SMoriah Waterland * Name: pkgIsPkgInGzOnly 277*5c51f124SMoriah Waterland * Description: determine if package is recorded as "in global zone only" 278*5c51f124SMoriah Waterland * by searching the specified open FILE for the specified package 279*5c51f124SMoriah Waterland * Arguments: a_fp - pointer to FILE handle open on file to search 280*5c51f124SMoriah Waterland * a_pkgInst - pointer to string representing the package instance 281*5c51f124SMoriah Waterland * (name) of the package to lookup 282*5c51f124SMoriah Waterland * Returns: boolean_t 283*5c51f124SMoriah Waterland * B_TRUE - package is recorded as "in global zone only" 284*5c51f124SMoriah Waterland * B_FALSE - package is NOT recorded as "in gz only" 285*5c51f124SMoriah Waterland */ 286*5c51f124SMoriah Waterland 287*5c51f124SMoriah Waterland boolean_t 288*5c51f124SMoriah Waterland pkgIsPkgInGzOnlyFP(FILE *a_fp, char *a_pkgInst) 289*5c51f124SMoriah Waterland { 290*5c51f124SMoriah Waterland char line[PATH_MAX+1]; 291*5c51f124SMoriah Waterland 292*5c51f124SMoriah Waterland /* entry assertions */ 293*5c51f124SMoriah Waterland 294*5c51f124SMoriah Waterland assert(a_fp != (FILE *)NULL); 295*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 296*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 297*5c51f124SMoriah Waterland 298*5c51f124SMoriah Waterland /* rewind the file to the beginning */ 299*5c51f124SMoriah Waterland 300*5c51f124SMoriah Waterland rewind(a_fp); 301*5c51f124SMoriah Waterland 302*5c51f124SMoriah Waterland /* read the file line by line searching for the specified package */ 303*5c51f124SMoriah Waterland 304*5c51f124SMoriah Waterland while (fgets(line, sizeof (line), a_fp) != (char *)NULL) { 305*5c51f124SMoriah Waterland int len; 306*5c51f124SMoriah Waterland 307*5c51f124SMoriah Waterland /* strip off trailing newlines */ 308*5c51f124SMoriah Waterland len = strlen(line); 309*5c51f124SMoriah Waterland while ((len > 0) && (line[len-1] == '\n')) { 310*5c51f124SMoriah Waterland line[--len] = '\0'; 311*5c51f124SMoriah Waterland } 312*5c51f124SMoriah Waterland 313*5c51f124SMoriah Waterland /* ignore blank and comment lines */ 314*5c51f124SMoriah Waterland if ((line[0] == '#') || (line[0] == '\0')) { 315*5c51f124SMoriah Waterland continue; 316*5c51f124SMoriah Waterland } 317*5c51f124SMoriah Waterland 318*5c51f124SMoriah Waterland /* return true if this is the package we are looking for */ 319*5c51f124SMoriah Waterland if (strcmp(a_pkgInst, line) == 0) { 320*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_PKG_IS_GZONLY, a_pkgInst); 321*5c51f124SMoriah Waterland return (B_TRUE); 322*5c51f124SMoriah Waterland } 323*5c51f124SMoriah Waterland } 324*5c51f124SMoriah Waterland 325*5c51f124SMoriah Waterland /* end of file - package not found */ 326*5c51f124SMoriah Waterland 327*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_PKG_NOT_GZONLY, a_pkgInst); 328*5c51f124SMoriah Waterland 329*5c51f124SMoriah Waterland return (B_FALSE); 330*5c51f124SMoriah Waterland } 331*5c51f124SMoriah Waterland 332*5c51f124SMoriah Waterland /* 333*5c51f124SMoriah Waterland * Name: pkgRemovePackageFromGzonlyList 334*5c51f124SMoriah Waterland * Description: Remove specified package from the global zone only package list 335*5c51f124SMoriah Waterland * file located at a specified root path 336*5c51f124SMoriah Waterland * Arguments: a_rootPath - pointer to string representing the root path 337*5c51f124SMoriah Waterland * where the global zone only package list file is 338*5c51f124SMoriah Waterland * located - NULL is the same as "/" 339*5c51f124SMoriah Waterland * a_pkgInst - pointer to string representing the package instance 340*5c51f124SMoriah Waterland * (name) of the package to remove 341*5c51f124SMoriah Waterland * Returns: boolean_t 342*5c51f124SMoriah Waterland * B_TRUE - package is successfully removed 343*5c51f124SMoriah Waterland * B_FALSE - failed to remove package from file 344*5c51f124SMoriah Waterland * NOTE: This function will create the file if it does not exist. 345*5c51f124SMoriah Waterland */ 346*5c51f124SMoriah Waterland 347*5c51f124SMoriah Waterland boolean_t 348*5c51f124SMoriah Waterland pkgRemovePackageFromGzonlyList(char *a_rootPath, char *a_pkgInst) 349*5c51f124SMoriah Waterland { 350*5c51f124SMoriah Waterland FILE *destFP; 351*5c51f124SMoriah Waterland FILE *srcFP; 352*5c51f124SMoriah Waterland boolean_t pkgremoved = B_FALSE; 353*5c51f124SMoriah Waterland char destPath[PATH_MAX]; 354*5c51f124SMoriah Waterland char line[PATH_MAX+1]; 355*5c51f124SMoriah Waterland char savePath[PATH_MAX]; 356*5c51f124SMoriah Waterland char srcPath[PATH_MAX]; 357*5c51f124SMoriah Waterland char timeb[BUFSIZ]; 358*5c51f124SMoriah Waterland int len; 359*5c51f124SMoriah Waterland struct tm *timep; 360*5c51f124SMoriah Waterland time_t clock; 361*5c51f124SMoriah Waterland 362*5c51f124SMoriah Waterland /* entry assertions */ 363*5c51f124SMoriah Waterland 364*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 365*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 366*5c51f124SMoriah Waterland 367*5c51f124SMoriah Waterland /* normalize root path */ 368*5c51f124SMoriah Waterland 369*5c51f124SMoriah Waterland if (a_rootPath == (char *)NULL) { 370*5c51f124SMoriah Waterland a_rootPath = ""; 371*5c51f124SMoriah Waterland } 372*5c51f124SMoriah Waterland 373*5c51f124SMoriah Waterland /* 374*5c51f124SMoriah Waterland * calculate paths to various objects 375*5c51f124SMoriah Waterland */ 376*5c51f124SMoriah Waterland 377*5c51f124SMoriah Waterland /* path to current "source" ingzonly file */ 378*5c51f124SMoriah Waterland 379*5c51f124SMoriah Waterland len = snprintf(srcPath, sizeof (srcPath), "%s/%s", 380*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 381*5c51f124SMoriah Waterland if (len > sizeof (srcPath)) { 382*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 383*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 384*5c51f124SMoriah Waterland return (B_FALSE); 385*5c51f124SMoriah Waterland } 386*5c51f124SMoriah Waterland 387*5c51f124SMoriah Waterland /* path to new "destination" ingzonly file */ 388*5c51f124SMoriah Waterland 389*5c51f124SMoriah Waterland len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp", 390*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 391*5c51f124SMoriah Waterland if (len > sizeof (srcPath)) { 392*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 393*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 394*5c51f124SMoriah Waterland return (B_FALSE); 395*5c51f124SMoriah Waterland } 396*5c51f124SMoriah Waterland 397*5c51f124SMoriah Waterland /* path to temporary "saved" ingzonly file */ 398*5c51f124SMoriah Waterland 399*5c51f124SMoriah Waterland len = snprintf(savePath, sizeof (savePath), "%s/%s.save", 400*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 401*5c51f124SMoriah Waterland if (len > sizeof (srcPath)) { 402*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 403*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 404*5c51f124SMoriah Waterland return (B_FALSE); 405*5c51f124SMoriah Waterland } 406*5c51f124SMoriah Waterland 407*5c51f124SMoriah Waterland /* open source file, creating if necessary */ 408*5c51f124SMoriah Waterland 409*5c51f124SMoriah Waterland srcFP = fopen(srcPath, "r+"); 410*5c51f124SMoriah Waterland if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) { 411*5c51f124SMoriah Waterland srcFP = fopen(srcPath, "w+"); 412*5c51f124SMoriah Waterland } 413*5c51f124SMoriah Waterland 414*5c51f124SMoriah Waterland /* error if could not open/create file */ 415*5c51f124SMoriah Waterland 416*5c51f124SMoriah Waterland if (srcFP == (FILE *)NULL) { 417*5c51f124SMoriah Waterland progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno)); 418*5c51f124SMoriah Waterland return (B_FALSE); 419*5c51f124SMoriah Waterland } 420*5c51f124SMoriah Waterland 421*5c51f124SMoriah Waterland /* open/create new destination file */ 422*5c51f124SMoriah Waterland 423*5c51f124SMoriah Waterland (void) remove(destPath); 424*5c51f124SMoriah Waterland destFP = fopen(destPath, "w"); 425*5c51f124SMoriah Waterland if (destFP == (FILE *)NULL) { 426*5c51f124SMoriah Waterland progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno)); 427*5c51f124SMoriah Waterland if (srcFP != (FILE *)NULL) { 428*5c51f124SMoriah Waterland (void) fclose(srcFP); 429*5c51f124SMoriah Waterland } 430*5c51f124SMoriah Waterland return (B_FALSE); 431*5c51f124SMoriah Waterland } 432*5c51f124SMoriah Waterland 433*5c51f124SMoriah Waterland /* add standard comment to beginning of file */ 434*5c51f124SMoriah Waterland 435*5c51f124SMoriah Waterland (void) time(&clock); 436*5c51f124SMoriah Waterland timep = localtime(&clock); 437*5c51f124SMoriah Waterland 438*5c51f124SMoriah Waterland (void) strftime(timeb, sizeof (timeb), "%c\n", timep); 439*5c51f124SMoriah Waterland 440*5c51f124SMoriah Waterland /* put standard header at the beginning of the file */ 441*5c51f124SMoriah Waterland 442*5c51f124SMoriah Waterland (void) fprintf(destFP, MSG_GZONLY_FILE_HEADER, 443*5c51f124SMoriah Waterland get_prog_name(), "remove", a_pkgInst, timeb); 444*5c51f124SMoriah Waterland 445*5c51f124SMoriah Waterland /* read source/write destination - removing specified package */ 446*5c51f124SMoriah Waterland 447*5c51f124SMoriah Waterland while (fgets(line, sizeof (line), srcFP) != (char *)NULL) { 448*5c51f124SMoriah Waterland int len; 449*5c51f124SMoriah Waterland 450*5c51f124SMoriah Waterland /* strip off trailing newlines */ 451*5c51f124SMoriah Waterland len = strlen(line); 452*5c51f124SMoriah Waterland while ((len > 0) && (line[len-1] == '\n')) { 453*5c51f124SMoriah Waterland line[--len] = '\0'; 454*5c51f124SMoriah Waterland } 455*5c51f124SMoriah Waterland 456*5c51f124SMoriah Waterland /* ignore blank and comment lines */ 457*5c51f124SMoriah Waterland if ((line[0] == '#') || (line[0] == '\0')) { 458*5c51f124SMoriah Waterland continue; 459*5c51f124SMoriah Waterland } 460*5c51f124SMoriah Waterland 461*5c51f124SMoriah Waterland /* add pkg if yet to add and pkg <= line */ 462*5c51f124SMoriah Waterland if ((pkgremoved == B_FALSE) && (strcmp(a_pkgInst, line) == 0)) { 463*5c51f124SMoriah Waterland pkgremoved = B_TRUE; 464*5c51f124SMoriah Waterland } else { 465*5c51f124SMoriah Waterland (void) fprintf(destFP, "%s\n", line); 466*5c51f124SMoriah Waterland } 467*5c51f124SMoriah Waterland } 468*5c51f124SMoriah Waterland 469*5c51f124SMoriah Waterland /* close both files */ 470*5c51f124SMoriah Waterland 471*5c51f124SMoriah Waterland (void) fclose(srcFP); 472*5c51f124SMoriah Waterland 473*5c51f124SMoriah Waterland (void) fclose(destFP); 474*5c51f124SMoriah Waterland 475*5c51f124SMoriah Waterland /* 476*5c51f124SMoriah Waterland * if package not found there is no need to update the original file 477*5c51f124SMoriah Waterland */ 478*5c51f124SMoriah Waterland 479*5c51f124SMoriah Waterland if (pkgremoved == B_FALSE) { 480*5c51f124SMoriah Waterland (void) unlink(destPath); 481*5c51f124SMoriah Waterland return (B_TRUE); 482*5c51f124SMoriah Waterland } 483*5c51f124SMoriah Waterland 484*5c51f124SMoriah Waterland /* 485*5c51f124SMoriah Waterland * Now we want to make a copy of the old gzonly file as a 486*5c51f124SMoriah Waterland * fail-safe. 487*5c51f124SMoriah Waterland */ 488*5c51f124SMoriah Waterland 489*5c51f124SMoriah Waterland if ((access(savePath, F_OK) == 0) && remove(savePath)) { 490*5c51f124SMoriah Waterland progerr(ERR_REMOVE, savePath, strerror(errno)); 491*5c51f124SMoriah Waterland (void) remove(destPath); 492*5c51f124SMoriah Waterland return (B_FALSE); 493*5c51f124SMoriah Waterland } 494*5c51f124SMoriah Waterland 495*5c51f124SMoriah Waterland if (link(srcPath, savePath) != 0) { 496*5c51f124SMoriah Waterland progerr(ERR_LINK, savePath, srcPath, strerror(errno)); 497*5c51f124SMoriah Waterland (void) remove(destPath); 498*5c51f124SMoriah Waterland return (B_FALSE); 499*5c51f124SMoriah Waterland } 500*5c51f124SMoriah Waterland 501*5c51f124SMoriah Waterland if (rename(destPath, srcPath) != 0) { 502*5c51f124SMoriah Waterland progerr(ERR_RENAME, destPath, srcPath, strerror(errno)); 503*5c51f124SMoriah Waterland if (rename(savePath, srcPath)) { 504*5c51f124SMoriah Waterland progerr(ERR_RENAME, savePath, srcPath, strerror(errno)); 505*5c51f124SMoriah Waterland } 506*5c51f124SMoriah Waterland (void) remove(destPath); 507*5c51f124SMoriah Waterland return (B_FALSE); 508*5c51f124SMoriah Waterland } 509*5c51f124SMoriah Waterland 510*5c51f124SMoriah Waterland if (remove(savePath) != 0) { 511*5c51f124SMoriah Waterland progerr(ERR_REMOVE, savePath, strerror(errno)); 512*5c51f124SMoriah Waterland } 513*5c51f124SMoriah Waterland 514*5c51f124SMoriah Waterland /* successfully removed package */ 515*5c51f124SMoriah Waterland 516*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_REMOVED_GZPKG, a_pkgInst); 517*5c51f124SMoriah Waterland 518*5c51f124SMoriah Waterland return (B_TRUE); 519*5c51f124SMoriah Waterland } 520*5c51f124SMoriah Waterland 521*5c51f124SMoriah Waterland /* 522*5c51f124SMoriah Waterland * Name: pkgAddPackageFromGzonlyList 523*5c51f124SMoriah Waterland * Description: Add specified package to the global zone only package list 524*5c51f124SMoriah Waterland * file located at a specified root path 525*5c51f124SMoriah Waterland * Arguments: a_rootPath - pointer to string representing the root path 526*5c51f124SMoriah Waterland * where the global zone only package list file is 527*5c51f124SMoriah Waterland * located - NULL is the same as "/" 528*5c51f124SMoriah Waterland * a_pkgInst - pointer to string representing the package instance 529*5c51f124SMoriah Waterland * (name) of the package to add 530*5c51f124SMoriah Waterland * Returns: boolean_t 531*5c51f124SMoriah Waterland * B_TRUE - package is successfully added 532*5c51f124SMoriah Waterland * B_FALSE - failed to add package to the file 533*5c51f124SMoriah Waterland * NOTE: This function will create the file if it does not exist. 534*5c51f124SMoriah Waterland */ 535*5c51f124SMoriah Waterland 536*5c51f124SMoriah Waterland boolean_t 537*5c51f124SMoriah Waterland pkgAddPackageToGzonlyList(char *a_pkgInst, char *a_rootPath) 538*5c51f124SMoriah Waterland { 539*5c51f124SMoriah Waterland FILE *destFP; 540*5c51f124SMoriah Waterland FILE *srcFP; 541*5c51f124SMoriah Waterland boolean_t pkgadded = B_FALSE; 542*5c51f124SMoriah Waterland char destPath[PATH_MAX]; 543*5c51f124SMoriah Waterland char line[PATH_MAX+1]; 544*5c51f124SMoriah Waterland char savePath[PATH_MAX]; 545*5c51f124SMoriah Waterland char srcPath[PATH_MAX]; 546*5c51f124SMoriah Waterland char timeb[BUFSIZ]; 547*5c51f124SMoriah Waterland int len; 548*5c51f124SMoriah Waterland struct tm *timep; 549*5c51f124SMoriah Waterland time_t clock; 550*5c51f124SMoriah Waterland 551*5c51f124SMoriah Waterland /* entry assertions */ 552*5c51f124SMoriah Waterland 553*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 554*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 555*5c51f124SMoriah Waterland 556*5c51f124SMoriah Waterland /* normalize root path */ 557*5c51f124SMoriah Waterland 558*5c51f124SMoriah Waterland if (a_rootPath == (char *)NULL) { 559*5c51f124SMoriah Waterland a_rootPath = ""; 560*5c51f124SMoriah Waterland } 561*5c51f124SMoriah Waterland 562*5c51f124SMoriah Waterland /* entry debugging info */ 563*5c51f124SMoriah Waterland 564*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_ADDGZPKG, a_pkgInst, a_rootPath); 565*5c51f124SMoriah Waterland 566*5c51f124SMoriah Waterland /* 567*5c51f124SMoriah Waterland * calculate paths to various objects 568*5c51f124SMoriah Waterland */ 569*5c51f124SMoriah Waterland 570*5c51f124SMoriah Waterland /* path to current "source" ingzonly file */ 571*5c51f124SMoriah Waterland 572*5c51f124SMoriah Waterland len = snprintf(srcPath, sizeof (srcPath), "%s/%s", 573*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 574*5c51f124SMoriah Waterland if (len > sizeof (srcPath)) { 575*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 576*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 577*5c51f124SMoriah Waterland return (B_FALSE); 578*5c51f124SMoriah Waterland } 579*5c51f124SMoriah Waterland 580*5c51f124SMoriah Waterland /* path to new "destination" ingzonly file */ 581*5c51f124SMoriah Waterland 582*5c51f124SMoriah Waterland len = snprintf(destPath, sizeof (destPath), "%s/%s.tmp", 583*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 584*5c51f124SMoriah Waterland if (len > sizeof (srcPath)) { 585*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 586*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 587*5c51f124SMoriah Waterland return (B_FALSE); 588*5c51f124SMoriah Waterland } 589*5c51f124SMoriah Waterland 590*5c51f124SMoriah Waterland /* path to temporary "saved" ingzonly file */ 591*5c51f124SMoriah Waterland 592*5c51f124SMoriah Waterland len = snprintf(savePath, sizeof (savePath), "%s/%s.save", 593*5c51f124SMoriah Waterland a_rootPath, GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 594*5c51f124SMoriah Waterland if (len > sizeof (srcPath)) { 595*5c51f124SMoriah Waterland progerr(ERR_CREATE_PATH_2, a_rootPath, 596*5c51f124SMoriah Waterland GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 597*5c51f124SMoriah Waterland return (B_FALSE); 598*5c51f124SMoriah Waterland } 599*5c51f124SMoriah Waterland 600*5c51f124SMoriah Waterland /* open source file, creating if necessary */ 601*5c51f124SMoriah Waterland 602*5c51f124SMoriah Waterland srcFP = fopen(srcPath, "r+"); 603*5c51f124SMoriah Waterland if ((srcFP == (FILE *)NULL) && (errno == ENOENT)) { 604*5c51f124SMoriah Waterland srcFP = fopen(srcPath, "w+"); 605*5c51f124SMoriah Waterland } 606*5c51f124SMoriah Waterland 607*5c51f124SMoriah Waterland /* error if could not open/create file */ 608*5c51f124SMoriah Waterland 609*5c51f124SMoriah Waterland if (srcFP == (FILE *)NULL) { 610*5c51f124SMoriah Waterland progerr(ERR_PKGOPS_OPEN_GZONLY, srcPath, strerror(errno)); 611*5c51f124SMoriah Waterland return (B_FALSE); 612*5c51f124SMoriah Waterland } 613*5c51f124SMoriah Waterland 614*5c51f124SMoriah Waterland /* open/create new destination file */ 615*5c51f124SMoriah Waterland 616*5c51f124SMoriah Waterland (void) remove(destPath); 617*5c51f124SMoriah Waterland destFP = fopen(destPath, "w"); 618*5c51f124SMoriah Waterland if (destFP == (FILE *)NULL) { 619*5c51f124SMoriah Waterland progerr(ERR_PKGOPS_TMPOPEN, destPath, strerror(errno)); 620*5c51f124SMoriah Waterland if (srcFP != (FILE *)NULL) { 621*5c51f124SMoriah Waterland (void) fclose(srcFP); 622*5c51f124SMoriah Waterland } 623*5c51f124SMoriah Waterland return (B_FALSE); 624*5c51f124SMoriah Waterland } 625*5c51f124SMoriah Waterland 626*5c51f124SMoriah Waterland /* add standard comment to beginning of file */ 627*5c51f124SMoriah Waterland 628*5c51f124SMoriah Waterland (void) time(&clock); 629*5c51f124SMoriah Waterland timep = localtime(&clock); 630*5c51f124SMoriah Waterland 631*5c51f124SMoriah Waterland (void) strftime(timeb, sizeof (timeb), "%c\n", timep); 632*5c51f124SMoriah Waterland 633*5c51f124SMoriah Waterland /* put standard header at the beginning of the file */ 634*5c51f124SMoriah Waterland 635*5c51f124SMoriah Waterland (void) fprintf(destFP, MSG_GZONLY_FILE_HEADER, 636*5c51f124SMoriah Waterland get_prog_name(), "add", a_pkgInst, timeb); 637*5c51f124SMoriah Waterland 638*5c51f124SMoriah Waterland /* read source/write destination; add package at appropriate location */ 639*5c51f124SMoriah Waterland 640*5c51f124SMoriah Waterland while (fgets(line, sizeof (line), srcFP) != (char *)NULL) { 641*5c51f124SMoriah Waterland int len; 642*5c51f124SMoriah Waterland 643*5c51f124SMoriah Waterland /* strip off trailing newlines */ 644*5c51f124SMoriah Waterland len = strlen(line); 645*5c51f124SMoriah Waterland while ((len > 0) && (line[len-1] == '\n')) { 646*5c51f124SMoriah Waterland line[--len] = '\0'; 647*5c51f124SMoriah Waterland } 648*5c51f124SMoriah Waterland 649*5c51f124SMoriah Waterland /* ignore blank and comment lines */ 650*5c51f124SMoriah Waterland if ((line[0] == '#') || (line[0] == '\0')) { 651*5c51f124SMoriah Waterland continue; 652*5c51f124SMoriah Waterland } 653*5c51f124SMoriah Waterland 654*5c51f124SMoriah Waterland /* add pkg if yet to add and pkg <= line */ 655*5c51f124SMoriah Waterland if ((pkgadded == B_FALSE) && (strcmp(a_pkgInst, line) <= 0)) { 656*5c51f124SMoriah Waterland if (strcmp(a_pkgInst, line) != 0) { 657*5c51f124SMoriah Waterland (void) fprintf(destFP, "%s\n", a_pkgInst); 658*5c51f124SMoriah Waterland } 659*5c51f124SMoriah Waterland pkgadded = B_TRUE; 660*5c51f124SMoriah Waterland } 661*5c51f124SMoriah Waterland 662*5c51f124SMoriah Waterland (void) fprintf(destFP, "%s\n", line); 663*5c51f124SMoriah Waterland } 664*5c51f124SMoriah Waterland 665*5c51f124SMoriah Waterland /* if package not added yet, add to end of the file */ 666*5c51f124SMoriah Waterland 667*5c51f124SMoriah Waterland if (pkgadded == B_FALSE) { 668*5c51f124SMoriah Waterland (void) fprintf(destFP, "%s\n", a_pkgInst); 669*5c51f124SMoriah Waterland } 670*5c51f124SMoriah Waterland 671*5c51f124SMoriah Waterland /* close both files */ 672*5c51f124SMoriah Waterland 673*5c51f124SMoriah Waterland (void) fclose(srcFP); 674*5c51f124SMoriah Waterland 675*5c51f124SMoriah Waterland (void) fclose(destFP); 676*5c51f124SMoriah Waterland 677*5c51f124SMoriah Waterland /* 678*5c51f124SMoriah Waterland * Now we want to make a copy of the old gzonly file as a 679*5c51f124SMoriah Waterland * fail-safe. 680*5c51f124SMoriah Waterland */ 681*5c51f124SMoriah Waterland 682*5c51f124SMoriah Waterland if ((access(savePath, F_OK) == 0) && remove(savePath)) { 683*5c51f124SMoriah Waterland progerr(ERR_REMOVE, savePath, strerror(errno)); 684*5c51f124SMoriah Waterland (void) remove(destPath); 685*5c51f124SMoriah Waterland return (B_FALSE); 686*5c51f124SMoriah Waterland } 687*5c51f124SMoriah Waterland 688*5c51f124SMoriah Waterland if (link(srcPath, savePath) != 0) { 689*5c51f124SMoriah Waterland progerr(ERR_LINK, savePath, srcPath, strerror(errno)); 690*5c51f124SMoriah Waterland (void) remove(destPath); 691*5c51f124SMoriah Waterland return (B_FALSE); 692*5c51f124SMoriah Waterland } 693*5c51f124SMoriah Waterland 694*5c51f124SMoriah Waterland if (rename(destPath, srcPath) != 0) { 695*5c51f124SMoriah Waterland progerr(ERR_RENAME, destPath, srcPath, strerror(errno)); 696*5c51f124SMoriah Waterland if (rename(savePath, srcPath)) { 697*5c51f124SMoriah Waterland progerr(ERR_RENAME, savePath, srcPath, strerror(errno)); 698*5c51f124SMoriah Waterland } 699*5c51f124SMoriah Waterland (void) remove(destPath); 700*5c51f124SMoriah Waterland return (B_FALSE); 701*5c51f124SMoriah Waterland } 702*5c51f124SMoriah Waterland 703*5c51f124SMoriah Waterland if (remove(savePath) != 0) { 704*5c51f124SMoriah Waterland progerr(ERR_REMOVE, savePath, strerror(errno)); 705*5c51f124SMoriah Waterland } 706*5c51f124SMoriah Waterland 707*5c51f124SMoriah Waterland /* successfully added package */ 708*5c51f124SMoriah Waterland 709*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_ADDED_GZPKG, a_pkgInst); 710*5c51f124SMoriah Waterland 711*5c51f124SMoriah Waterland return (B_TRUE); 712*5c51f124SMoriah Waterland } 713*5c51f124SMoriah Waterland 714*5c51f124SMoriah Waterland /* 715*5c51f124SMoriah Waterland * Name: pkginfoParamTruth 716*5c51f124SMoriah Waterland * Description: Search pkginfo file for specified parameter/value pair 717*5c51f124SMoriah Waterland * Arguments: a_fp - Pointer to FILE handle open on pkginfo file to search 718*5c51f124SMoriah Waterland * a_param - Pointer to string representing the parameter name 719*5c51f124SMoriah Waterland * to search for 720*5c51f124SMoriah Waterland * a_value - Pointer to string representing the "success" value 721*5c51f124SMoriah Waterland * being searched for 722*5c51f124SMoriah Waterland * a_default - determine results if parameter NOT found 723*5c51f124SMoriah Waterland * B_TRUE - parameter is TRUE if not found 724*5c51f124SMoriah Waterland * B_FALSE - parameter is FALSE if not found 725*5c51f124SMoriah Waterland * Returns: boolean_t 726*5c51f124SMoriah Waterland * B_TRUE - the parameter was found and matched the specified value 727*5c51f124SMoriah Waterland * OR the paramter was not found and a_default == B_TRUE 728*5c51f124SMoriah Waterland * B_FALSE - the parameter was found and did NOT match the value 729*5c51f124SMoriah Waterland * OR the paramter was not found and a_default == B_FALSE 730*5c51f124SMoriah Waterland */ 731*5c51f124SMoriah Waterland 732*5c51f124SMoriah Waterland boolean_t 733*5c51f124SMoriah Waterland pkginfoParamTruth(FILE *a_fp, char *a_param, char *a_value, boolean_t a_default) 734*5c51f124SMoriah Waterland { 735*5c51f124SMoriah Waterland char *param; 736*5c51f124SMoriah Waterland boolean_t result; 737*5c51f124SMoriah Waterland 738*5c51f124SMoriah Waterland /* entry assertions */ 739*5c51f124SMoriah Waterland 740*5c51f124SMoriah Waterland assert(a_fp != (FILE *)NULL); 741*5c51f124SMoriah Waterland assert(a_param != (char *)NULL); 742*5c51f124SMoriah Waterland assert(*a_param != '\0'); 743*5c51f124SMoriah Waterland assert(a_value != (char *)NULL); 744*5c51f124SMoriah Waterland assert(*a_value != '\0'); 745*5c51f124SMoriah Waterland 746*5c51f124SMoriah Waterland /* rewind the file to the beginning */ 747*5c51f124SMoriah Waterland 748*5c51f124SMoriah Waterland rewind(a_fp); 749*5c51f124SMoriah Waterland 750*5c51f124SMoriah Waterland /* search pkginfo file for the specified parameter */ 751*5c51f124SMoriah Waterland 752*5c51f124SMoriah Waterland param = fpkgparam(a_fp, a_param); 753*5c51f124SMoriah Waterland 754*5c51f124SMoriah Waterland if (param == (char *)NULL) { 755*5c51f124SMoriah Waterland /* parameter not found - return default */ 756*5c51f124SMoriah Waterland result = a_default; 757*5c51f124SMoriah Waterland } else if (*param == '\0') { 758*5c51f124SMoriah Waterland /* parameter found but no value - return default */ 759*5c51f124SMoriah Waterland result = a_default; 760*5c51f124SMoriah Waterland } else if (strcasecmp(param, a_value) == 0) { 761*5c51f124SMoriah Waterland /* paramter found - matches value */ 762*5c51f124SMoriah Waterland result = B_TRUE; 763*5c51f124SMoriah Waterland } else { 764*5c51f124SMoriah Waterland /* parameter found - does not match value */ 765*5c51f124SMoriah Waterland result = B_FALSE; 766*5c51f124SMoriah Waterland } 767*5c51f124SMoriah Waterland 768*5c51f124SMoriah Waterland /* exit debugging info */ 769*5c51f124SMoriah Waterland 770*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_PARAMTRUTH_RESULTS, 771*5c51f124SMoriah Waterland a_param, a_value, a_default == B_TRUE ? "true" : "false", 772*5c51f124SMoriah Waterland param ? param : "?", result == B_TRUE ? "true" : "false"); 773*5c51f124SMoriah Waterland 774*5c51f124SMoriah Waterland /* if parameter value found, free results */ 775*5c51f124SMoriah Waterland 776*5c51f124SMoriah Waterland if (param != (char *)NULL) { 777*5c51f124SMoriah Waterland (void) free(param); 778*5c51f124SMoriah Waterland } 779*5c51f124SMoriah Waterland 780*5c51f124SMoriah Waterland /* return results of search */ 781*5c51f124SMoriah Waterland 782*5c51f124SMoriah Waterland return (result); 783*5c51f124SMoriah Waterland } 784*5c51f124SMoriah Waterland 785*5c51f124SMoriah Waterland /* 786*5c51f124SMoriah Waterland * Name: pkgGetPackageList 787*5c51f124SMoriah Waterland * Description: Determine list of packages based on list of packages that are 788*5c51f124SMoriah Waterland * available, category of packages to select, and list of packages 789*5c51f124SMoriah Waterland * to select. 790*5c51f124SMoriah Waterland * Arguments: r_pkgList - pointer to pointer to string array where the list 791*5c51f124SMoriah Waterland * of selected packages will be returned 792*5c51f124SMoriah Waterland * a_argv - pointer to string array containing list of packages 793*5c51f124SMoriah Waterland * to select 794*5c51f124SMoriah Waterland * a_optind - index into string array of first package to select 795*5c51f124SMoriah Waterland * a_categories - pointer to string representing the categories of 796*5c51f124SMoriah Waterland * packages to select 797*5c51f124SMoriah Waterland * a_categoryList - pointer to string array representing a list 798*5c51f124SMoriah Waterland * of categories to select 799*5c51f124SMoriah Waterland * a_pkgdev - package dev containing packages that can be selected 800*5c51f124SMoriah Waterland * Returns: int 801*5c51f124SMoriah Waterland * == 0 - packages found r_pkgList contains results package list retrieved 802*5c51f124SMoriah Waterland * == -1 - no packages found (errno == ENOPKG) 803*5c51f124SMoriah Waterland * != 0 - "quit" value entered by user 804*5c51f124SMoriah Waterland * NOTE: If both a category and a list of packages to select are provided 805*5c51f124SMoriah Waterland * the category is used over the list of packages provided 806*5c51f124SMoriah Waterland * NOTE: If neither a category nor a list of packages to select are 807*5c51f124SMoriah Waterland * provided, an error is returned 808*5c51f124SMoriah Waterland */ 809*5c51f124SMoriah Waterland 810*5c51f124SMoriah Waterland int 811*5c51f124SMoriah Waterland pkgGetPackageList(char ***r_pkgList, char **a_argv, int a_optind, 812*5c51f124SMoriah Waterland char *a_categories, char **a_categoryList, struct pkgdev *a_pkgdev) 813*5c51f124SMoriah Waterland { 814*5c51f124SMoriah Waterland char *all_pkgs[4] = {"all", NULL}; 815*5c51f124SMoriah Waterland 816*5c51f124SMoriah Waterland /* entry assertions */ 817*5c51f124SMoriah Waterland 818*5c51f124SMoriah Waterland assert(a_pkgdev != (struct pkgdev *)NULL); 819*5c51f124SMoriah Waterland assert(a_pkgdev->dirname != (char *)NULL); 820*5c51f124SMoriah Waterland assert(*a_pkgdev->dirname != '\0'); 821*5c51f124SMoriah Waterland assert(r_pkgList != (char ***)NULL); 822*5c51f124SMoriah Waterland assert(a_argv != (char **)NULL); 823*5c51f124SMoriah Waterland 824*5c51f124SMoriah Waterland /* entry debugging info */ 825*5c51f124SMoriah Waterland 826*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GETPKGLIST_ENTRY); 827*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GETPKGLIST_ARGS, a_pkgdev->dirname, 828*5c51f124SMoriah Waterland a_categories ? a_categories : "?"); 829*5c51f124SMoriah Waterland 830*5c51f124SMoriah Waterland /* reset returned package list handle */ 831*5c51f124SMoriah Waterland 832*5c51f124SMoriah Waterland *r_pkgList = (char **)NULL; 833*5c51f124SMoriah Waterland 834*5c51f124SMoriah Waterland /* 835*5c51f124SMoriah Waterland * generate list of packages to be removed: if removing by category, 836*5c51f124SMoriah Waterland * then generate package list based on all packages by category, 837*5c51f124SMoriah Waterland * else generate package list based on all packages specified. 838*5c51f124SMoriah Waterland */ 839*5c51f124SMoriah Waterland 840*5c51f124SMoriah Waterland if (a_categories != NULL) { 841*5c51f124SMoriah Waterland /* generate package list from all packages in given category */ 842*5c51f124SMoriah Waterland 843*5c51f124SMoriah Waterland *r_pkgList = gpkglist(a_pkgdev->dirname, &all_pkgs[0], 844*5c51f124SMoriah Waterland a_categoryList); 845*5c51f124SMoriah Waterland 846*5c51f124SMoriah Waterland if (*r_pkgList == NULL) { 847*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_CATFAILED, a_categories); 848*5c51f124SMoriah Waterland progerr(ERR_CAT_FND, a_categories); 849*5c51f124SMoriah Waterland return (1); 850*5c51f124SMoriah Waterland } 851*5c51f124SMoriah Waterland 852*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_CATOK, a_categories); 853*5c51f124SMoriah Waterland 854*5c51f124SMoriah Waterland return (0); 855*5c51f124SMoriah Waterland } 856*5c51f124SMoriah Waterland 857*5c51f124SMoriah Waterland /* generate package list from specified packages */ 858*5c51f124SMoriah Waterland 859*5c51f124SMoriah Waterland *r_pkgList = gpkglist(a_pkgdev->dirname, &a_argv[a_optind], NULL); 860*5c51f124SMoriah Waterland 861*5c51f124SMoriah Waterland /* if list generated return results */ 862*5c51f124SMoriah Waterland 863*5c51f124SMoriah Waterland if (*r_pkgList != NULL) { 864*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_OK); 865*5c51f124SMoriah Waterland return (0); 866*5c51f124SMoriah Waterland } 867*5c51f124SMoriah Waterland 868*5c51f124SMoriah Waterland /* handle error from gpkglist */ 869*5c51f124SMoriah Waterland 870*5c51f124SMoriah Waterland switch (errno) { 871*5c51f124SMoriah Waterland case ENOPKG: /* no packages */ 872*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_ENOPKG); 873*5c51f124SMoriah Waterland return (-1); 874*5c51f124SMoriah Waterland 875*5c51f124SMoriah Waterland case ESRCH: 876*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_ESRCH); 877*5c51f124SMoriah Waterland return (1); 878*5c51f124SMoriah Waterland 879*5c51f124SMoriah Waterland case EINTR: 880*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_EINTR); 881*5c51f124SMoriah Waterland return (3); 882*5c51f124SMoriah Waterland 883*5c51f124SMoriah Waterland default: 884*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_GPKGLIST_UNKNOWN, errno); 885*5c51f124SMoriah Waterland progerr(ERR_GPKGLIST_ERROR); 886*5c51f124SMoriah Waterland return (99); 887*5c51f124SMoriah Waterland } 888*5c51f124SMoriah Waterland } 889*5c51f124SMoriah Waterland 890*5c51f124SMoriah Waterland /* 891*5c51f124SMoriah Waterland * Name: pkgMatchInherited 892*5c51f124SMoriah Waterland * Description: given a pointer to a "source" and a "destination" for an object, 893*5c51f124SMoriah Waterland * along with other attributes of the object, determine if the 894*5c51f124SMoriah Waterland * object is already installed and is current. 895*5c51f124SMoriah Waterland * Arguments: a_src - pointer to string representing the "source" file to 896*5c51f124SMoriah Waterland * verify - this would be the current temporary location of 897*5c51f124SMoriah Waterland * the file that would be installed 898*5c51f124SMoriah Waterland * a_dst - pointer to string representing the "destination" file to 899*5c51f124SMoriah Waterland * verify - this would be the ultimate destination for the 900*5c51f124SMoriah Waterland * file if installed 901*5c51f124SMoriah Waterland * a_rootDir - pointer to string representing the "root directory" 902*5c51f124SMoriah Waterland * where the package is being installed 903*5c51f124SMoriah Waterland * a_mode - final "mode" file should have when installed 904*5c51f124SMoriah Waterland * a_modtime - final "modtime" file should have when installed 905*5c51f124SMoriah Waterland * a_ftype - contents "type" of file (f/e/v/s/l) 906*5c51f124SMoriah Waterland * a_cksum - final "checksum" file should have when installed 907*5c51f124SMoriah Waterland * Returns: boolean_t 908*5c51f124SMoriah Waterland * B_TRUE - the specified source file MATCHES the file 909*5c51f124SMoriah Waterland * located at the specified destination 910*5c51f124SMoriah Waterland * B_FALSE - the specified source files does NOT match 911*5c51f124SMoriah Waterland * the file located at the specified destination 912*5c51f124SMoriah Waterland */ 913*5c51f124SMoriah Waterland 914*5c51f124SMoriah Waterland boolean_t 915*5c51f124SMoriah Waterland pkgMatchInherited(char *a_src, char *a_dst, char *a_rootDir, 916*5c51f124SMoriah Waterland char a_mode, time_t a_modtime, char a_ftype, unsigned long a_cksum) 917*5c51f124SMoriah Waterland { 918*5c51f124SMoriah Waterland char cwd[PATH_MAX+1] = {'\0'}; 919*5c51f124SMoriah Waterland char dstpath[PATH_MAX+1]; 920*5c51f124SMoriah Waterland int cksumerr; 921*5c51f124SMoriah Waterland int n; 922*5c51f124SMoriah Waterland struct stat statbufDst; 923*5c51f124SMoriah Waterland struct stat statbufSrc; 924*5c51f124SMoriah Waterland unsigned long dstcksum; 925*5c51f124SMoriah Waterland unsigned long srcksum; 926*5c51f124SMoriah Waterland 927*5c51f124SMoriah Waterland /* entry assertions */ 928*5c51f124SMoriah Waterland 929*5c51f124SMoriah Waterland assert(a_src != (char *)NULL); 930*5c51f124SMoriah Waterland assert(*a_src != '\0'); 931*5c51f124SMoriah Waterland assert(a_dst != (char *)NULL); 932*5c51f124SMoriah Waterland assert(*a_dst != '\0'); 933*5c51f124SMoriah Waterland 934*5c51f124SMoriah Waterland /* normalize root directory */ 935*5c51f124SMoriah Waterland 936*5c51f124SMoriah Waterland if ((a_rootDir == (char *)NULL) || (*a_rootDir == '\0')) { 937*5c51f124SMoriah Waterland a_rootDir = "/"; 938*5c51f124SMoriah Waterland } 939*5c51f124SMoriah Waterland 940*5c51f124SMoriah Waterland /* entry debugging */ 941*5c51f124SMoriah Waterland 942*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_MATCHINHERIT_ENTRY); 943*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_MATCHINHERIT_ARGS, a_src, a_dst, a_rootDir, 944*5c51f124SMoriah Waterland a_mode, a_modtime, a_ftype, a_cksum); 945*5c51f124SMoriah Waterland 946*5c51f124SMoriah Waterland /* save current working directory - resolvepath can change it */ 947*5c51f124SMoriah Waterland 948*5c51f124SMoriah Waterland (void) getcwd(cwd, sizeof (cwd)); 949*5c51f124SMoriah Waterland 950*5c51f124SMoriah Waterland n = resolvepath(a_dst, dstpath, sizeof (dstpath)); 951*5c51f124SMoriah Waterland if (n <= 0) { 952*5c51f124SMoriah Waterland if (errno != ENOENT) { 953*5c51f124SMoriah Waterland progerr(ERR_RESOLVEPATH, a_dst, strerror(errno)); 954*5c51f124SMoriah Waterland } 955*5c51f124SMoriah Waterland (void) chdir(cwd); 956*5c51f124SMoriah Waterland return (B_FALSE); 957*5c51f124SMoriah Waterland } 958*5c51f124SMoriah Waterland dstpath[n++] = '\0'; /* make sure string is terminated */ 959*5c51f124SMoriah Waterland 960*5c51f124SMoriah Waterland /* return false if path is not in inherited file system space */ 961*5c51f124SMoriah Waterland 962*5c51f124SMoriah Waterland if (!z_path_is_inherited(dstpath, a_ftype, a_rootDir)) { 963*5c51f124SMoriah Waterland return (B_FALSE); 964*5c51f124SMoriah Waterland } 965*5c51f124SMoriah Waterland 966*5c51f124SMoriah Waterland /* 967*5c51f124SMoriah Waterland * path is in inherited file system space: verify existence 968*5c51f124SMoriah Waterland */ 969*5c51f124SMoriah Waterland 970*5c51f124SMoriah Waterland /* return false if source file cannot be stat()ed */ 971*5c51f124SMoriah Waterland 972*5c51f124SMoriah Waterland if (stat(a_src, &statbufSrc) != 0) { 973*5c51f124SMoriah Waterland progerr(ERR_STAT, a_src, strerror(errno)); 974*5c51f124SMoriah Waterland return (B_FALSE); 975*5c51f124SMoriah Waterland } 976*5c51f124SMoriah Waterland 977*5c51f124SMoriah Waterland /* return false if destination file cannot be stat()ed */ 978*5c51f124SMoriah Waterland 979*5c51f124SMoriah Waterland if (stat(dstpath, &statbufDst) != 0) { 980*5c51f124SMoriah Waterland progerr(ERR_STAT, dstpath, strerror(errno)); 981*5c51f124SMoriah Waterland return (B_FALSE); 982*5c51f124SMoriah Waterland } 983*5c51f124SMoriah Waterland 984*5c51f124SMoriah Waterland /* 985*5c51f124SMoriah Waterland * if this is an editable or volatile file, then the only 986*5c51f124SMoriah Waterland * thing to guarantee is that the file exists - the file 987*5c51f124SMoriah Waterland * attributes do not need to match 988*5c51f124SMoriah Waterland */ 989*5c51f124SMoriah Waterland 990*5c51f124SMoriah Waterland /* editable file only needs to exist */ 991*5c51f124SMoriah Waterland 992*5c51f124SMoriah Waterland if (a_ftype == 'e') { 993*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_EDITABLE_EXISTS, dstpath); 994*5c51f124SMoriah Waterland return (B_TRUE); 995*5c51f124SMoriah Waterland } 996*5c51f124SMoriah Waterland 997*5c51f124SMoriah Waterland /* volatile file only needs to exist */ 998*5c51f124SMoriah Waterland 999*5c51f124SMoriah Waterland if (a_ftype == 'v') { 1000*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_VOLATILE_EXISTS, dstpath); 1001*5c51f124SMoriah Waterland return (B_TRUE); 1002*5c51f124SMoriah Waterland } 1003*5c51f124SMoriah Waterland 1004*5c51f124SMoriah Waterland /* 1005*5c51f124SMoriah Waterland * verify modtime if file is not modifiable after install 1006*5c51f124SMoriah Waterland */ 1007*5c51f124SMoriah Waterland 1008*5c51f124SMoriah Waterland /* return false if source and destination have different mod times */ 1009*5c51f124SMoriah Waterland 1010*5c51f124SMoriah Waterland if (statbufSrc.st_mtim.tv_sec != statbufDst.st_mtim.tv_sec) { 1011*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_MOD_MISMATCH, a_src, 1012*5c51f124SMoriah Waterland statbufSrc.st_mtim.tv_sec, dstpath, 1013*5c51f124SMoriah Waterland statbufDst.st_mtim.tv_sec); 1014*5c51f124SMoriah Waterland return (B_FALSE); 1015*5c51f124SMoriah Waterland } 1016*5c51f124SMoriah Waterland 1017*5c51f124SMoriah Waterland /* return false if destination does not have required mod time */ 1018*5c51f124SMoriah Waterland 1019*5c51f124SMoriah Waterland if (statbufDst.st_mtim.tv_sec != a_modtime) { 1020*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_MOD_MISMATCH, dstpath, 1021*5c51f124SMoriah Waterland statbufDst.st_mtim.tv_sec, "source", a_modtime); 1022*5c51f124SMoriah Waterland return (B_FALSE); 1023*5c51f124SMoriah Waterland } 1024*5c51f124SMoriah Waterland 1025*5c51f124SMoriah Waterland /* 1026*5c51f124SMoriah Waterland * verify checksums of both files 1027*5c51f124SMoriah Waterland */ 1028*5c51f124SMoriah Waterland 1029*5c51f124SMoriah Waterland /* generate checksum of installed file */ 1030*5c51f124SMoriah Waterland 1031*5c51f124SMoriah Waterland cksumerr = 0; 1032*5c51f124SMoriah Waterland dstcksum = compute_checksum(&cksumerr, dstpath); 1033*5c51f124SMoriah Waterland if (cksumerr != 0) { 1034*5c51f124SMoriah Waterland progerr(ERR_CANNOT_CKSUM_FILE, dstpath, strerror(errno)); 1035*5c51f124SMoriah Waterland return (B_FALSE); 1036*5c51f124SMoriah Waterland } 1037*5c51f124SMoriah Waterland 1038*5c51f124SMoriah Waterland /* return false if destination does not match recorded checksum */ 1039*5c51f124SMoriah Waterland 1040*5c51f124SMoriah Waterland if (dstcksum != a_cksum) { 1041*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_CKSUM_MISMATCH, dstpath, dstcksum, 1042*5c51f124SMoriah Waterland "source", a_cksum); 1043*5c51f124SMoriah Waterland return (B_FALSE); 1044*5c51f124SMoriah Waterland } 1045*5c51f124SMoriah Waterland 1046*5c51f124SMoriah Waterland /* generate checksum of file to install */ 1047*5c51f124SMoriah Waterland 1048*5c51f124SMoriah Waterland cksumerr = 0; 1049*5c51f124SMoriah Waterland srcksum = compute_checksum(&cksumerr, a_src); 1050*5c51f124SMoriah Waterland if (cksumerr != 0) { 1051*5c51f124SMoriah Waterland progerr(ERR_CANNOT_CKSUM_FILE, a_src, strerror(errno)); 1052*5c51f124SMoriah Waterland return (B_FALSE); 1053*5c51f124SMoriah Waterland } 1054*5c51f124SMoriah Waterland 1055*5c51f124SMoriah Waterland /* return false if source to install does not match recorded checksum */ 1056*5c51f124SMoriah Waterland 1057*5c51f124SMoriah Waterland if (srcksum != dstcksum) { 1058*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_CKSUM_MISMATCH, a_src, srcksum, dstpath, 1059*5c51f124SMoriah Waterland dstcksum); 1060*5c51f124SMoriah Waterland return (B_FALSE); 1061*5c51f124SMoriah Waterland } 1062*5c51f124SMoriah Waterland 1063*5c51f124SMoriah Waterland /* src/dest identical - return true */ 1064*5c51f124SMoriah Waterland 1065*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_IS_INHERITED, dstpath, ""); 1066*5c51f124SMoriah Waterland 1067*5c51f124SMoriah Waterland return (B_TRUE); 1068*5c51f124SMoriah Waterland } 1069*5c51f124SMoriah Waterland 1070*5c51f124SMoriah Waterland /* 1071*5c51f124SMoriah Waterland * return string representing path to "global zone only file" 1072*5c51f124SMoriah Waterland */ 1073*5c51f124SMoriah Waterland 1074*5c51f124SMoriah Waterland char * 1075*5c51f124SMoriah Waterland pkgGetGzOnlyPath(void) 1076*5c51f124SMoriah Waterland { 1077*5c51f124SMoriah Waterland return (GLOBALZONE_ONLY_PACKAGE_FILE_PATH); 1078*5c51f124SMoriah Waterland } 1079*5c51f124SMoriah Waterland 1080*5c51f124SMoriah Waterland /* 1081*5c51f124SMoriah Waterland * Name: pkgAddThisZonePackage 1082*5c51f124SMoriah Waterland * Description: Add specified package to internal list of "this zone only" pkgs 1083*5c51f124SMoriah Waterland * Arguments: a_pkgInst - name of package to add to list 1084*5c51f124SMoriah Waterland * Returns: void 1085*5c51f124SMoriah Waterland */ 1086*5c51f124SMoriah Waterland 1087*5c51f124SMoriah Waterland void 1088*5c51f124SMoriah Waterland pkgAddThisZonePackage(char *a_pkgInst) 1089*5c51f124SMoriah Waterland { 1090*5c51f124SMoriah Waterland /* entry assertions */ 1091*5c51f124SMoriah Waterland 1092*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 1093*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 1094*5c51f124SMoriah Waterland 1095*5c51f124SMoriah Waterland /* do not duplicate entries */ 1096*5c51f124SMoriah Waterland 1097*5c51f124SMoriah Waterland if (pkgPackageIsThisZone(a_pkgInst) == B_TRUE) { 1098*5c51f124SMoriah Waterland return; 1099*5c51f124SMoriah Waterland } 1100*5c51f124SMoriah Waterland 1101*5c51f124SMoriah Waterland /* add package name to internal list */ 1102*5c51f124SMoriah Waterland 1103*5c51f124SMoriah Waterland if (thisZonePackages == (char **)NULL) { 1104*5c51f124SMoriah Waterland thisZonePackages = 1105*5c51f124SMoriah Waterland (char **)calloc(2, sizeof (char **)); 1106*5c51f124SMoriah Waterland } else { 1107*5c51f124SMoriah Waterland thisZonePackages = 1108*5c51f124SMoriah Waterland (char **)realloc(thisZonePackages, 1109*5c51f124SMoriah Waterland sizeof (char **)*(numThisZonePackages+2)); 1110*5c51f124SMoriah Waterland } 1111*5c51f124SMoriah Waterland 1112*5c51f124SMoriah Waterland /* handle out of memory error */ 1113*5c51f124SMoriah Waterland 1114*5c51f124SMoriah Waterland if (thisZonePackages == (char **)NULL) { 1115*5c51f124SMoriah Waterland progerr(ERR_MEMORY, errno); 1116*5c51f124SMoriah Waterland quit(99); 1117*5c51f124SMoriah Waterland } 1118*5c51f124SMoriah Waterland 1119*5c51f124SMoriah Waterland /* add this entry to the end of the list */ 1120*5c51f124SMoriah Waterland 1121*5c51f124SMoriah Waterland thisZonePackages[numThisZonePackages] = strdup(a_pkgInst); 1122*5c51f124SMoriah Waterland if (thisZonePackages[numThisZonePackages] == (char *)NULL) { 1123*5c51f124SMoriah Waterland progerr(ERR_MEMORY, errno); 1124*5c51f124SMoriah Waterland quit(99); 1125*5c51f124SMoriah Waterland } 1126*5c51f124SMoriah Waterland 1127*5c51f124SMoriah Waterland numThisZonePackages++; 1128*5c51f124SMoriah Waterland 1129*5c51f124SMoriah Waterland /* make sure end of the list is properly terminated */ 1130*5c51f124SMoriah Waterland 1131*5c51f124SMoriah Waterland thisZonePackages[numThisZonePackages] = (char *)NULL; 1132*5c51f124SMoriah Waterland 1133*5c51f124SMoriah Waterland /* exit debugging info */ 1134*5c51f124SMoriah Waterland 1135*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_ADD_TZP, numThisZonePackages, 1136*5c51f124SMoriah Waterland thisZonePackages[numThisZonePackages-1]); 1137*5c51f124SMoriah Waterland } 1138*5c51f124SMoriah Waterland 1139*5c51f124SMoriah Waterland /* 1140*5c51f124SMoriah Waterland * Name: pkgPackageIsThisZone 1141*5c51f124SMoriah Waterland * Description: Determine if the specified package is marked to be installed 1142*5c51f124SMoriah Waterland * in this zone only 1143*5c51f124SMoriah Waterland * Arguments: a_pkgInst - pointer to string representing package name to check 1144*5c51f124SMoriah Waterland * Returns: boolean_t 1145*5c51f124SMoriah Waterland * B_TRUE - the package IS "this zone only" 1146*5c51f124SMoriah Waterland * B_FALSE - the paackage is NOT "this zone only" 1147*5c51f124SMoriah Waterland */ 1148*5c51f124SMoriah Waterland 1149*5c51f124SMoriah Waterland boolean_t 1150*5c51f124SMoriah Waterland pkgPackageIsThisZone(char *a_pkgInst) 1151*5c51f124SMoriah Waterland { 1152*5c51f124SMoriah Waterland int n; 1153*5c51f124SMoriah Waterland 1154*5c51f124SMoriah Waterland /* entry assertions */ 1155*5c51f124SMoriah Waterland 1156*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 1157*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 1158*5c51f124SMoriah Waterland 1159*5c51f124SMoriah Waterland /* if no inherited file systems, there can be no match */ 1160*5c51f124SMoriah Waterland 1161*5c51f124SMoriah Waterland if (numThisZonePackages == 0) { 1162*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_NOT_THISZONE, a_pkgInst); 1163*5c51f124SMoriah Waterland return (B_FALSE); 1164*5c51f124SMoriah Waterland } 1165*5c51f124SMoriah Waterland 1166*5c51f124SMoriah Waterland /* 1167*5c51f124SMoriah Waterland * see if this package is in the "this zone only" list 1168*5c51f124SMoriah Waterland */ 1169*5c51f124SMoriah Waterland 1170*5c51f124SMoriah Waterland for (n = 0; n < numThisZonePackages; n++) { 1171*5c51f124SMoriah Waterland if (strcmp(a_pkgInst, thisZonePackages[n]) == 0) { 1172*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_IS_THISZONE, a_pkgInst); 1173*5c51f124SMoriah Waterland return (B_TRUE); 1174*5c51f124SMoriah Waterland } 1175*5c51f124SMoriah Waterland } 1176*5c51f124SMoriah Waterland 1177*5c51f124SMoriah Waterland /* path is not in "this zone only" list */ 1178*5c51f124SMoriah Waterland 1179*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_IS_NOT_THISZONE, a_pkgInst); 1180*5c51f124SMoriah Waterland 1181*5c51f124SMoriah Waterland return (B_FALSE); 1182*5c51f124SMoriah Waterland } 1183*5c51f124SMoriah Waterland 1184*5c51f124SMoriah Waterland /* 1185*5c51f124SMoriah Waterland * Name: pkgLocateHighestInst 1186*5c51f124SMoriah Waterland * Description: Locate the highest installed instance of a package 1187*5c51f124SMoriah Waterland * Arguments: r_path - [RO, *RW] - (char *) 1188*5c51f124SMoriah Waterland * Pointer to buffer where the full path to the top level 1189*5c51f124SMoriah Waterland * directory containing the latest instance of the 1190*5c51f124SMoriah Waterland * specified package is located is placed. 1191*5c51f124SMoriah Waterland * r_pathLen - [RO, *RO] - (int) 1192*5c51f124SMoriah Waterland * Integer representing the size of r_path in bytes. 1193*5c51f124SMoriah Waterland * r_pkgInst - [RO, *RW] - (char *) 1194*5c51f124SMoriah Waterland * Pointer to buffer where the package instance name of the 1195*5c51f124SMoriah Waterland * latest instance of the specified package is placed. 1196*5c51f124SMoriah Waterland * r_pkgInstLen - [RO, *RO] - (int) 1197*5c51f124SMoriah Waterland * Integer representing the size of r_pkgInst in bytes. 1198*5c51f124SMoriah Waterland * a_rootPath - [RO, *RO] - (char *) 1199*5c51f124SMoriah Waterland * Pointer to string representing the root path to look 1200*5c51f124SMoriah Waterland * for the latest instance of the specified package. 1201*5c51f124SMoriah Waterland * a_pkgInst - [RO, *RO] - (char *) 1202*5c51f124SMoriah Waterland * Pointer to string representing the name of the package 1203*5c51f124SMoriah Waterland * to locate the latest installed instance of. 1204*5c51f124SMoriah Waterland */ 1205*5c51f124SMoriah Waterland 1206*5c51f124SMoriah Waterland void 1207*5c51f124SMoriah Waterland pkgLocateHighestInst(char *r_path, int r_pathLen, char *r_pkgInst, 1208*5c51f124SMoriah Waterland int r_pkgInstLen, char *a_rootPath, char *a_pkgInst) 1209*5c51f124SMoriah Waterland { 1210*5c51f124SMoriah Waterland char pkgInstPath[PATH_MAX] = {'\0'}; 1211*5c51f124SMoriah Waterland char pkgWild[PKGSIZ+1] = {'\0'}; 1212*5c51f124SMoriah Waterland char pkgName[PKGSIZ+1] = {'\0'}; 1213*5c51f124SMoriah Waterland int npkgs; 1214*5c51f124SMoriah Waterland struct pkginfo *pinf = (struct pkginfo *)NULL; 1215*5c51f124SMoriah Waterland 1216*5c51f124SMoriah Waterland /* entry assertions */ 1217*5c51f124SMoriah Waterland 1218*5c51f124SMoriah Waterland assert(r_path != (char *)NULL); 1219*5c51f124SMoriah Waterland assert(r_pathLen > 0); 1220*5c51f124SMoriah Waterland assert(r_pkgInst != (char *)NULL); 1221*5c51f124SMoriah Waterland assert(r_pkgInstLen > 0); 1222*5c51f124SMoriah Waterland assert(a_pkgInst != (char *)NULL); 1223*5c51f124SMoriah Waterland assert(*a_pkgInst != '\0'); 1224*5c51f124SMoriah Waterland 1225*5c51f124SMoriah Waterland /* normalize root path */ 1226*5c51f124SMoriah Waterland 1227*5c51f124SMoriah Waterland if ((a_rootPath == (char *)NULL) || (strcmp(a_rootPath, "/") == 0)) { 1228*5c51f124SMoriah Waterland a_rootPath = ""; 1229*5c51f124SMoriah Waterland } 1230*5c51f124SMoriah Waterland 1231*5c51f124SMoriah Waterland /* construct path to package repository directory (eg. /var/sadm/pkg) */ 1232*5c51f124SMoriah Waterland 1233*5c51f124SMoriah Waterland (void) snprintf(pkgInstPath, sizeof (pkgInstPath), "%s%s", a_rootPath, 1234*5c51f124SMoriah Waterland PKGLOC); 1235*5c51f124SMoriah Waterland 1236*5c51f124SMoriah Waterland /* entry debugging info */ 1237*5c51f124SMoriah Waterland 1238*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_LOCHIGH_ENTRY); 1239*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_LOCHIGH_ARGS, pkgInstPath, a_pkgInst); 1240*5c51f124SMoriah Waterland 1241*5c51f124SMoriah Waterland /* reset returned path/package instance so both ares empty */ 1242*5c51f124SMoriah Waterland 1243*5c51f124SMoriah Waterland *r_path = '\0'; 1244*5c51f124SMoriah Waterland *r_pkgInst = '\0'; 1245*5c51f124SMoriah Waterland 1246*5c51f124SMoriah Waterland /* remove any architecture extension */ 1247*5c51f124SMoriah Waterland 1248*5c51f124SMoriah Waterland pkgstrGetToken_r((char *)NULL, a_pkgInst, 0, ".", 1249*5c51f124SMoriah Waterland pkgName, sizeof (pkgName)); 1250*5c51f124SMoriah Waterland 1251*5c51f124SMoriah Waterland /* make sure that the package name is valid and can be wild carded */ 1252*5c51f124SMoriah Waterland 1253*5c51f124SMoriah Waterland if (pkgnmchk(pkgName, NULL, 0) || strchr(pkgName, '.')) { 1254*5c51f124SMoriah Waterland progerr(ERR_PKGOPS_LOCHIGH_BAD_PKGNAME, pkgName); 1255*5c51f124SMoriah Waterland quit(99); 1256*5c51f124SMoriah Waterland } 1257*5c51f124SMoriah Waterland 1258*5c51f124SMoriah Waterland /* create wild card specification for this package instance */ 1259*5c51f124SMoriah Waterland 1260*5c51f124SMoriah Waterland (void) snprintf(pkgWild, sizeof (pkgWild), "%s.*", pkgName); 1261*5c51f124SMoriah Waterland 1262*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_LOCHIGH_WILDCARD, pkgName, pkgWild); 1263*5c51f124SMoriah Waterland 1264*5c51f124SMoriah Waterland /* 1265*5c51f124SMoriah Waterland * inspect the system to determine if any instances of the 1266*5c51f124SMoriah Waterland * package being installed already exist on the system 1267*5c51f124SMoriah Waterland */ 1268*5c51f124SMoriah Waterland 1269*5c51f124SMoriah Waterland for (npkgs = 0; ; npkgs++) { 1270*5c51f124SMoriah Waterland char *savePkgdir; 1271*5c51f124SMoriah Waterland int r; 1272*5c51f124SMoriah Waterland 1273*5c51f124SMoriah Waterland /* allocate new pinfo structure for use in the pkginfo call */ 1274*5c51f124SMoriah Waterland 1275*5c51f124SMoriah Waterland pinf = _pkginfoFactory(); 1276*5c51f124SMoriah Waterland 1277*5c51f124SMoriah Waterland /* 1278*5c51f124SMoriah Waterland * lookup the specified package; the first call will cause the 1279*5c51f124SMoriah Waterland * pkgdir directory to be opened - it will be closed when the 1280*5c51f124SMoriah Waterland * end of directory is read and pkginfo() returns != 0. You must 1281*5c51f124SMoriah Waterland * cycle through all instances until pkginfo() returns != 0. 1282*5c51f124SMoriah Waterland * NOTE: pkginfo() requires the global variable 'pkgdir' be set 1283*5c51f124SMoriah Waterland * to the package installed directory (<root>/var/sadm/pkg). 1284*5c51f124SMoriah Waterland */ 1285*5c51f124SMoriah Waterland 1286*5c51f124SMoriah Waterland savePkgdir = pkgdir; 1287*5c51f124SMoriah Waterland pkgdir = pkgInstPath; 1288*5c51f124SMoriah Waterland 1289*5c51f124SMoriah Waterland r = pkginfo(pinf, pkgWild, NULL, NULL); 1290*5c51f124SMoriah Waterland 1291*5c51f124SMoriah Waterland pkgdir = savePkgdir; 1292*5c51f124SMoriah Waterland 1293*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_PKGINFO_RETURNED, pkgName, r); 1294*5c51f124SMoriah Waterland 1295*5c51f124SMoriah Waterland /* break out of loop of no package found */ 1296*5c51f124SMoriah Waterland 1297*5c51f124SMoriah Waterland if (r != 0) { 1298*5c51f124SMoriah Waterland pkginfoFree(&pinf); 1299*5c51f124SMoriah Waterland break; 1300*5c51f124SMoriah Waterland } 1301*5c51f124SMoriah Waterland 1302*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_LOCHIGH_INSTANCE, npkgs, 1303*5c51f124SMoriah Waterland pinf->pkginst ? pinf->pkginst : "", 1304*5c51f124SMoriah Waterland pinf->name ? pinf->name : "", 1305*5c51f124SMoriah Waterland pinf->arch ? pinf->arch : "", 1306*5c51f124SMoriah Waterland pinf->version ? pinf->version : "", 1307*5c51f124SMoriah Waterland pinf->vendor ? pinf->vendor : "", 1308*5c51f124SMoriah Waterland pinf->basedir ? pinf->basedir : "", 1309*5c51f124SMoriah Waterland pinf->catg ? pinf->catg : "", 1310*5c51f124SMoriah Waterland pinf->status); 1311*5c51f124SMoriah Waterland 1312*5c51f124SMoriah Waterland /* save path/instance name for this instance found */ 1313*5c51f124SMoriah Waterland 1314*5c51f124SMoriah Waterland (void) strlcpy(r_pkgInst, pinf->pkginst, r_pkgInstLen); 1315*5c51f124SMoriah Waterland pkgstrPrintf_r(r_path, r_pathLen, "%s%s/%s", a_rootPath, 1316*5c51f124SMoriah Waterland PKGLOC, pinf->pkginst); 1317*5c51f124SMoriah Waterland 1318*5c51f124SMoriah Waterland pkginfoFree(&pinf); 1319*5c51f124SMoriah Waterland } 1320*5c51f124SMoriah Waterland 1321*5c51f124SMoriah Waterland echoDebug(DBG_PKGOPS_LOCHIGH_RETURN, npkgs, r_pkgInst, r_path); 1322*5c51f124SMoriah Waterland } 1323*5c51f124SMoriah Waterland 1324*5c51f124SMoriah Waterland /* 1325*5c51f124SMoriah Waterland * Name: pkgTestInstalled 1326*5c51f124SMoriah Waterland * Description: determine if package is installed at specified root path 1327*5c51f124SMoriah Waterland * Arguments: a_packageName - name of package to test 1328*5c51f124SMoriah Waterland * a_rootPath - root path of alternative root to test 1329*5c51f124SMoriah Waterland * Returns: B_TRUE - package is installed 1330*5c51f124SMoriah Waterland * B_FALSE - package is not installed 1331*5c51f124SMoriah Waterland */ 1332*5c51f124SMoriah Waterland 1333*5c51f124SMoriah Waterland boolean_t 1334*5c51f124SMoriah Waterland pkgTestInstalled(char *a_packageName, char *a_rootPath) 1335*5c51f124SMoriah Waterland { 1336*5c51f124SMoriah Waterland char cmd[MAXPATHLEN+1]; 1337*5c51f124SMoriah Waterland int rc; 1338*5c51f124SMoriah Waterland 1339*5c51f124SMoriah Waterland /* entry assertions */ 1340*5c51f124SMoriah Waterland 1341*5c51f124SMoriah Waterland assert(a_packageName != (char *)NULL); 1342*5c51f124SMoriah Waterland assert(*a_packageName != '\0'); 1343*5c51f124SMoriah Waterland assert(a_rootPath != (char *)NULL); 1344*5c51f124SMoriah Waterland assert(a_rootPath != '\0'); 1345*5c51f124SMoriah Waterland 1346*5c51f124SMoriah Waterland /* entry debugging info */ 1347*5c51f124SMoriah Waterland 1348*5c51f124SMoriah Waterland echoDebug(DBG_PKG_TEST_EXISTENCE, a_packageName, a_rootPath); 1349*5c51f124SMoriah Waterland 1350*5c51f124SMoriah Waterland /* 1351*5c51f124SMoriah Waterland * create pkginfo command to execute: 1352*5c51f124SMoriah Waterland * /usr/bin/pkginfo -q <packageName> 1353*5c51f124SMoriah Waterland */ 1354*5c51f124SMoriah Waterland (void) snprintf(cmd, sizeof (cmd), 1355*5c51f124SMoriah Waterland "%s -q %s", PKGINFO_CMD, a_packageName); 1356*5c51f124SMoriah Waterland 1357*5c51f124SMoriah Waterland /* execute command */ 1358*5c51f124SMoriah Waterland 1359*5c51f124SMoriah Waterland rc = system(cmd); 1360*5c51f124SMoriah Waterland 1361*5c51f124SMoriah Waterland /* return success if pkginfo returns "0" */ 1362*5c51f124SMoriah Waterland 1363*5c51f124SMoriah Waterland if (rc == 0) { 1364*5c51f124SMoriah Waterland echoDebug(DBG_PKG_INSTALLED, a_packageName, a_rootPath); 1365*5c51f124SMoriah Waterland return (B_TRUE); 1366*5c51f124SMoriah Waterland } 1367*5c51f124SMoriah Waterland 1368*5c51f124SMoriah Waterland /* package not installed */ 1369*5c51f124SMoriah Waterland 1370*5c51f124SMoriah Waterland echoDebug(DBG_PKG_NOT_INSTALLED, a_packageName, a_rootPath); 1371*5c51f124SMoriah Waterland 1372*5c51f124SMoriah Waterland return (B_FALSE); 1373*5c51f124SMoriah Waterland } 1374*5c51f124SMoriah Waterland 1375*5c51f124SMoriah Waterland /* 1376*5c51f124SMoriah Waterland * ***************************************************************************** 1377*5c51f124SMoriah Waterland * static internal (private) functions 1378*5c51f124SMoriah Waterland * ***************************************************************************** 1379*5c51f124SMoriah Waterland */ 1380*5c51f124SMoriah Waterland 1381*5c51f124SMoriah Waterland static void 1382*5c51f124SMoriah Waterland _pkginfoInit(struct pkginfo *a_info) 1383*5c51f124SMoriah Waterland { 1384*5c51f124SMoriah Waterland /* entry assertions */ 1385*5c51f124SMoriah Waterland 1386*5c51f124SMoriah Waterland assert(a_info != (struct pkginfo *)NULL); 1387*5c51f124SMoriah Waterland 1388*5c51f124SMoriah Waterland /* free previously allocated space */ 1389*5c51f124SMoriah Waterland 1390*5c51f124SMoriah Waterland if (a_info->pkginst) { 1391*5c51f124SMoriah Waterland free(a_info->pkginst); 1392*5c51f124SMoriah Waterland if (a_info->arch) 1393*5c51f124SMoriah Waterland free(a_info->arch); 1394*5c51f124SMoriah Waterland if (a_info->version) 1395*5c51f124SMoriah Waterland free(a_info->version); 1396*5c51f124SMoriah Waterland if (a_info->basedir) 1397*5c51f124SMoriah Waterland free(a_info->basedir); 1398*5c51f124SMoriah Waterland if (a_info->name) 1399*5c51f124SMoriah Waterland free(a_info->name); 1400*5c51f124SMoriah Waterland if (a_info->vendor) 1401*5c51f124SMoriah Waterland free(a_info->vendor); 1402*5c51f124SMoriah Waterland if (a_info->catg) 1403*5c51f124SMoriah Waterland free(a_info->catg); 1404*5c51f124SMoriah Waterland } 1405*5c51f124SMoriah Waterland 1406*5c51f124SMoriah Waterland a_info->pkginst = NULL; 1407*5c51f124SMoriah Waterland a_info->arch = a_info->version = NULL; 1408*5c51f124SMoriah Waterland a_info->basedir = a_info->name = NULL; 1409*5c51f124SMoriah Waterland a_info->vendor = a_info->catg = NULL; 1410*5c51f124SMoriah Waterland a_info->status = PI_UNKNOWN; 1411*5c51f124SMoriah Waterland } 1412*5c51f124SMoriah Waterland 1413*5c51f124SMoriah Waterland static struct pkginfo * 1414*5c51f124SMoriah Waterland _pkginfoFactory(void) 1415*5c51f124SMoriah Waterland { 1416*5c51f124SMoriah Waterland struct pkginfo *pinf; 1417*5c51f124SMoriah Waterland 1418*5c51f124SMoriah Waterland pinf = (struct pkginfo *)calloc(1, sizeof (struct pkginfo)); 1419*5c51f124SMoriah Waterland if (pinf == (struct pkginfo *)NULL) { 1420*5c51f124SMoriah Waterland progerr(ERR_MEM); 1421*5c51f124SMoriah Waterland exit(1); 1422*5c51f124SMoriah Waterland } 1423*5c51f124SMoriah Waterland 1424*5c51f124SMoriah Waterland _pkginfoInit(pinf); 1425*5c51f124SMoriah Waterland return (pinf); 1426*5c51f124SMoriah Waterland } 1427