19781SMoriah.Waterland@Sun.COM /* 29781SMoriah.Waterland@Sun.COM * CDDL HEADER START 39781SMoriah.Waterland@Sun.COM * 49781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 59781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 69781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 79781SMoriah.Waterland@Sun.COM * 89781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 99781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 109781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 119781SMoriah.Waterland@Sun.COM * and limitations under the License. 129781SMoriah.Waterland@Sun.COM * 139781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 149781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 159781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 169781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 179781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 189781SMoriah.Waterland@Sun.COM * 199781SMoriah.Waterland@Sun.COM * CDDL HEADER END 209781SMoriah.Waterland@Sun.COM */ 219781SMoriah.Waterland@Sun.COM 229781SMoriah.Waterland@Sun.COM /* 23*9869SCasper.Dik@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 249781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 259781SMoriah.Waterland@Sun.COM */ 269781SMoriah.Waterland@Sun.COM 279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */ 299781SMoriah.Waterland@Sun.COM 309781SMoriah.Waterland@Sun.COM 319781SMoriah.Waterland@Sun.COM #include <stdio.h> 329781SMoriah.Waterland@Sun.COM #include <errno.h> 339781SMoriah.Waterland@Sun.COM #include <string.h> 349781SMoriah.Waterland@Sun.COM #include <limits.h> 359781SMoriah.Waterland@Sun.COM #include <stdlib.h> 369781SMoriah.Waterland@Sun.COM #include <unistd.h> 379781SMoriah.Waterland@Sun.COM #include <sys/types.h> 389781SMoriah.Waterland@Sun.COM #include <pkgstrct.h> 399781SMoriah.Waterland@Sun.COM #include <locale.h> 409781SMoriah.Waterland@Sun.COM #include <libintl.h> 419781SMoriah.Waterland@Sun.COM #include <pkglib.h> 429781SMoriah.Waterland@Sun.COM #include "install.h" 439781SMoriah.Waterland@Sun.COM #include "libinst.h" 449781SMoriah.Waterland@Sun.COM #include "libadm.h" 459781SMoriah.Waterland@Sun.COM 469781SMoriah.Waterland@Sun.COM extern struct cfextra **extlist; 479781SMoriah.Waterland@Sun.COM extern struct cfent **eptlist; 489781SMoriah.Waterland@Sun.COM 499781SMoriah.Waterland@Sun.COM extern char *pkginst; 509781SMoriah.Waterland@Sun.COM 519781SMoriah.Waterland@Sun.COM #define ERR_WRITE "write of intermediate contents file failed" 529781SMoriah.Waterland@Sun.COM 539781SMoriah.Waterland@Sun.COM static char *check_db_entry(VFP_T *, struct cfextra *, int, char *, int *); 549781SMoriah.Waterland@Sun.COM 559781SMoriah.Waterland@Sun.COM /*ARGSUSED*/ 569781SMoriah.Waterland@Sun.COM int 57*9869SCasper.Dik@Sun.COM dofinal(PKGserver server, VFP_T *vfpo, int rmflag, char *myclass, char *prog) 589781SMoriah.Waterland@Sun.COM { 599781SMoriah.Waterland@Sun.COM struct cfextra entry; 609781SMoriah.Waterland@Sun.COM int n, indx, dbchg; 619781SMoriah.Waterland@Sun.COM char *save_path = NULL; 629781SMoriah.Waterland@Sun.COM 639781SMoriah.Waterland@Sun.COM entry.cf_ent.pinfo = NULL; 649781SMoriah.Waterland@Sun.COM entry.fsys_value = BADFSYS; 659781SMoriah.Waterland@Sun.COM entry.fsys_base = BADFSYS; 669781SMoriah.Waterland@Sun.COM indx = 0; 679781SMoriah.Waterland@Sun.COM 689781SMoriah.Waterland@Sun.COM while (extlist && extlist[indx] && (extlist[indx]->cf_ent.ftype == 'i')) 699781SMoriah.Waterland@Sun.COM indx++; 709781SMoriah.Waterland@Sun.COM 719781SMoriah.Waterland@Sun.COM dbchg = 0; 729781SMoriah.Waterland@Sun.COM 73*9869SCasper.Dik@Sun.COM if (pkgopenfilter(server, pkginst) != 0) 74*9869SCasper.Dik@Sun.COM quit(99); 75*9869SCasper.Dik@Sun.COM 76*9869SCasper.Dik@Sun.COM while (n = srchcfile(&(entry.cf_ent), "*", server)) { 779781SMoriah.Waterland@Sun.COM if (n < 0) { 789781SMoriah.Waterland@Sun.COM char *errstr = getErrstr(); 79*9869SCasper.Dik@Sun.COM progerr(gettext("bad entry read in contents file")); 80*9869SCasper.Dik@Sun.COM logerr(gettext("pathname=%s"), 81*9869SCasper.Dik@Sun.COM (entry.cf_ent.path && *(entry.cf_ent.path)) ? 82*9869SCasper.Dik@Sun.COM entry.cf_ent.path : "Unknown"); 839781SMoriah.Waterland@Sun.COM logerr(gettext("problem=%s"), 84*9869SCasper.Dik@Sun.COM (errstr && *errstr) ? errstr : "Unknown"); 859781SMoriah.Waterland@Sun.COM quit(99); 869781SMoriah.Waterland@Sun.COM } 87*9869SCasper.Dik@Sun.COM save_path = check_db_entry(vfpo, &entry, rmflag, myclass, 88*9869SCasper.Dik@Sun.COM &dbchg); 899781SMoriah.Waterland@Sun.COM 909781SMoriah.Waterland@Sun.COM /* Restore original server-relative path, if needed */ 919781SMoriah.Waterland@Sun.COM if (save_path != NULL) { 929781SMoriah.Waterland@Sun.COM entry.cf_ent.path = save_path; 939781SMoriah.Waterland@Sun.COM save_path = NULL; 949781SMoriah.Waterland@Sun.COM } 959781SMoriah.Waterland@Sun.COM } 969781SMoriah.Waterland@Sun.COM 97*9869SCasper.Dik@Sun.COM pkgclosefilter(server); 98*9869SCasper.Dik@Sun.COM 999781SMoriah.Waterland@Sun.COM return (dbchg); 1009781SMoriah.Waterland@Sun.COM } 1019781SMoriah.Waterland@Sun.COM 1029781SMoriah.Waterland@Sun.COM static char * 1039781SMoriah.Waterland@Sun.COM check_db_entry(VFP_T *vfpo, struct cfextra *entry, int rmflag, char *myclass, 1049781SMoriah.Waterland@Sun.COM int *dbchg) 1059781SMoriah.Waterland@Sun.COM { 1069781SMoriah.Waterland@Sun.COM struct pinfo *pinfo; 1079781SMoriah.Waterland@Sun.COM int fs_entry; 1089781SMoriah.Waterland@Sun.COM char *save_path = NULL; 1099781SMoriah.Waterland@Sun.COM char *tp; 1109781SMoriah.Waterland@Sun.COM 1119781SMoriah.Waterland@Sun.COM if (myclass && strcmp(myclass, entry->cf_ent.pkg_class)) { 112*9869SCasper.Dik@Sun.COM /* 113*9869SCasper.Dik@Sun.COM * We already have it in the database we don't want 114*9869SCasper.Dik@Sun.COM * to modify it. 115*9869SCasper.Dik@Sun.COM */ 1169781SMoriah.Waterland@Sun.COM return (NULL); 1179781SMoriah.Waterland@Sun.COM } 1189781SMoriah.Waterland@Sun.COM 1199781SMoriah.Waterland@Sun.COM /* 1209781SMoriah.Waterland@Sun.COM * Now scan each package instance holding this file or 1219781SMoriah.Waterland@Sun.COM * directory and see if it matches the package we are 1229781SMoriah.Waterland@Sun.COM * updating here. 1239781SMoriah.Waterland@Sun.COM */ 1249781SMoriah.Waterland@Sun.COM pinfo = entry->cf_ent.pinfo; 1259781SMoriah.Waterland@Sun.COM while (pinfo) { 1269781SMoriah.Waterland@Sun.COM if (strcmp(pkginst, pinfo->pkg) == 0) 1279781SMoriah.Waterland@Sun.COM break; 1289781SMoriah.Waterland@Sun.COM pinfo = pinfo->next; 1299781SMoriah.Waterland@Sun.COM } 1309781SMoriah.Waterland@Sun.COM 1319781SMoriah.Waterland@Sun.COM /* 1329781SMoriah.Waterland@Sun.COM * If pinfo == NULL at this point, then this file or 1339781SMoriah.Waterland@Sun.COM * directory isn't part of the package of interest. 134*9869SCasper.Dik@Sun.COM * So the code below executes only on files in the package 1359781SMoriah.Waterland@Sun.COM * of interest. 1369781SMoriah.Waterland@Sun.COM */ 1379781SMoriah.Waterland@Sun.COM 138*9869SCasper.Dik@Sun.COM if (pinfo == NULL) 139*9869SCasper.Dik@Sun.COM return (NULL); 140*9869SCasper.Dik@Sun.COM 141*9869SCasper.Dik@Sun.COM if (rmflag && (pinfo->status == RM_RDY)) { 142*9869SCasper.Dik@Sun.COM *dbchg = 1; 143*9869SCasper.Dik@Sun.COM 144*9869SCasper.Dik@Sun.COM (void) eptstat(&(entry->cf_ent), pkginst, '@'); 1459781SMoriah.Waterland@Sun.COM 146*9869SCasper.Dik@Sun.COM if (entry->cf_ent.npkgs) { 147*9869SCasper.Dik@Sun.COM if (putcvfpfile(&(entry->cf_ent), vfpo)) { 148*9869SCasper.Dik@Sun.COM progerr(gettext(ERR_WRITE)); 149*9869SCasper.Dik@Sun.COM quit(99); 150*9869SCasper.Dik@Sun.COM } 151*9869SCasper.Dik@Sun.COM } else if (entry->cf_ent.path != NULL) { 152*9869SCasper.Dik@Sun.COM (void) vfpSetModified(vfpo); 153*9869SCasper.Dik@Sun.COM /* add "-<path>" to the file */ 154*9869SCasper.Dik@Sun.COM vfpPutc(vfpo, '-'); 155*9869SCasper.Dik@Sun.COM vfpPuts(vfpo, entry->cf_ent.path); 156*9869SCasper.Dik@Sun.COM vfpPutc(vfpo, '\n'); 157*9869SCasper.Dik@Sun.COM } 158*9869SCasper.Dik@Sun.COM return (NULL); 1599781SMoriah.Waterland@Sun.COM 160*9869SCasper.Dik@Sun.COM } else if (!rmflag && (pinfo->status == INST_RDY)) { 161*9869SCasper.Dik@Sun.COM *dbchg = 1; 1629781SMoriah.Waterland@Sun.COM 163*9869SCasper.Dik@Sun.COM /* tp is the server-relative path */ 164*9869SCasper.Dik@Sun.COM tp = fixpath(entry->cf_ent.path); 165*9869SCasper.Dik@Sun.COM /* save_path is the cmd line path */ 166*9869SCasper.Dik@Sun.COM save_path = entry->cf_ent.path; 167*9869SCasper.Dik@Sun.COM /* entry has the server-relative path */ 168*9869SCasper.Dik@Sun.COM entry->cf_ent.path = tp; 1699781SMoriah.Waterland@Sun.COM 170*9869SCasper.Dik@Sun.COM /* 171*9869SCasper.Dik@Sun.COM * The next if statement figures out how 172*9869SCasper.Dik@Sun.COM * the contents file entry should be 173*9869SCasper.Dik@Sun.COM * annotated. 174*9869SCasper.Dik@Sun.COM * 175*9869SCasper.Dik@Sun.COM * Don't install or verify objects for 176*9869SCasper.Dik@Sun.COM * remote, read-only filesystems. We 177*9869SCasper.Dik@Sun.COM * need only verify their presence and 178*9869SCasper.Dik@Sun.COM * flag them appropriately from some 179*9869SCasper.Dik@Sun.COM * server. Otherwise, ok to do final 180*9869SCasper.Dik@Sun.COM * check. 181*9869SCasper.Dik@Sun.COM */ 182*9869SCasper.Dik@Sun.COM fs_entry = fsys(entry->cf_ent.path); 1839781SMoriah.Waterland@Sun.COM 184*9869SCasper.Dik@Sun.COM if (is_remote_fs_n(fs_entry) && !is_fs_writeable_n(fs_entry)) { 185*9869SCasper.Dik@Sun.COM /* 186*9869SCasper.Dik@Sun.COM * Mark it shared whether it's present 187*9869SCasper.Dik@Sun.COM * or not. life's too funny for me 188*9869SCasper.Dik@Sun.COM * to explain. 189*9869SCasper.Dik@Sun.COM */ 190*9869SCasper.Dik@Sun.COM pinfo->status = SERVED_FILE; 1919781SMoriah.Waterland@Sun.COM 1929781SMoriah.Waterland@Sun.COM /* 193*9869SCasper.Dik@Sun.COM * restore for now. This may 194*9869SCasper.Dik@Sun.COM * chg soon. 195*9869SCasper.Dik@Sun.COM */ 196*9869SCasper.Dik@Sun.COM entry->cf_ent.path = save_path; 197*9869SCasper.Dik@Sun.COM } else { 198*9869SCasper.Dik@Sun.COM /* 199*9869SCasper.Dik@Sun.COM * If the object is accessible, check 200*9869SCasper.Dik@Sun.COM * the new entry for existence and 201*9869SCasper.Dik@Sun.COM * attributes. If there's a problem, 202*9869SCasper.Dik@Sun.COM * mark it NOT_FND; otherwise, 203*9869SCasper.Dik@Sun.COM * ENTRY_OK. 2049781SMoriah.Waterland@Sun.COM */ 205*9869SCasper.Dik@Sun.COM if (is_mounted_n(fs_entry)) { 206*9869SCasper.Dik@Sun.COM int n; 207*9869SCasper.Dik@Sun.COM 208*9869SCasper.Dik@Sun.COM n = finalck((&entry->cf_ent), 1, 1, B_FALSE); 2099781SMoriah.Waterland@Sun.COM 210*9869SCasper.Dik@Sun.COM pinfo->status = ENTRY_OK; 211*9869SCasper.Dik@Sun.COM if (n != 0) { 212*9869SCasper.Dik@Sun.COM pinfo->status = NOT_FND; 213*9869SCasper.Dik@Sun.COM } 214*9869SCasper.Dik@Sun.COM } 215*9869SCasper.Dik@Sun.COM 216*9869SCasper.Dik@Sun.COM /* 217*9869SCasper.Dik@Sun.COM * It's not remote, read-only but it 218*9869SCasper.Dik@Sun.COM * may look that way to the client. 219*9869SCasper.Dik@Sun.COM * If it does, overwrite the above 220*9869SCasper.Dik@Sun.COM * result - mark it shared. 221*9869SCasper.Dik@Sun.COM */ 222*9869SCasper.Dik@Sun.COM if (is_served_n(fs_entry)) 2239781SMoriah.Waterland@Sun.COM pinfo->status = SERVED_FILE; 2249781SMoriah.Waterland@Sun.COM 225*9869SCasper.Dik@Sun.COM /* restore original path */ 226*9869SCasper.Dik@Sun.COM entry->cf_ent.path = save_path; 227*9869SCasper.Dik@Sun.COM /* and clear save_path */ 228*9869SCasper.Dik@Sun.COM save_path = NULL; 2299781SMoriah.Waterland@Sun.COM } 2309781SMoriah.Waterland@Sun.COM } 2319781SMoriah.Waterland@Sun.COM 2329781SMoriah.Waterland@Sun.COM /* Output entry to contents file. */ 2339781SMoriah.Waterland@Sun.COM if (putcvfpfile(&(entry->cf_ent), vfpo)) { 2349781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_WRITE)); 2359781SMoriah.Waterland@Sun.COM quit(99); 2369781SMoriah.Waterland@Sun.COM } 2379781SMoriah.Waterland@Sun.COM 2389781SMoriah.Waterland@Sun.COM return (save_path); 2399781SMoriah.Waterland@Sun.COM } 240