1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #include <stdio.h> 32 #include <errno.h> 33 #include <string.h> 34 #include <limits.h> 35 #include <stdlib.h> 36 #include <unistd.h> 37 #include <sys/types.h> 38 #include <pkgstrct.h> 39 #include <locale.h> 40 #include <libintl.h> 41 #include <pkglib.h> 42 #include <libadm.h> 43 #include <libinst.h> 44 45 extern int dbchg, warnflag, otherstoo; 46 extern char *pkginst; 47 48 #define EPTMALLOC 128 49 50 #define ERR_WRENT "write of entry failed, errno=%d" 51 #define ERR_MEMORY "no memory, errno=%d" 52 #define ERR_READ_C "bad read of contents file" 53 #define ERR_READ_DB "bad read of the database" 54 55 extern struct cfent **eptlist; 56 extern int eptnum; 57 58 int 59 delmap(int flag, char *pkginst, PKGserver *pkgserver, VFP_T **tmpfp) 60 { 61 struct cfent *ept; 62 struct pinfo *pinfo; 63 int n; 64 char *unknown = "Unknown"; 65 66 67 if (!ocfile(pkgserver, tmpfp, 0L) || 68 pkgopenfilter(*pkgserver, pkginst) != 0) { 69 quit(99); 70 } 71 72 /* re-use any memory used to store pathnames */ 73 (void) pathdup(NULL); 74 75 if (eptlist != NULL) 76 free(eptlist); 77 eptlist = (struct cfent **)calloc(EPTMALLOC, 78 sizeof (struct cfent *)); 79 if (eptlist == NULL) { 80 progerr(gettext(ERR_MEMORY), errno); 81 quit(99); 82 } 83 84 ept = (struct cfent *)calloc(1, 85 (unsigned)sizeof (struct cfent)); 86 if (!ept) { 87 progerr(gettext(ERR_MEMORY), errno); 88 quit(99); 89 } 90 91 eptnum = 0; 92 while (n = srchcfile(ept, "*", *pkgserver)) { 93 if (n < 0) { 94 char *errstr = getErrstr(); 95 progerr(gettext("bad read of contents file")); 96 progerr(gettext("pathname=%s"), 97 (ept->path && *ept->path) ? ept->path : 98 unknown); 99 progerr(gettext("problem=%s"), 100 (errstr && *errstr) ? errstr : unknown); 101 exit(99); 102 } 103 pinfo = eptstat(ept, pkginst, (flag ? '@' : '-')); 104 if (ept->npkgs > 0) { 105 if (putcvfpfile(ept, *tmpfp)) { 106 progerr(gettext(ERR_WRENT), errno); 107 quit(99); 108 } 109 } else if (ept->path != NULL) { 110 (void) vfpSetModified(*tmpfp); 111 /* add "-<path>" to the file */ 112 vfpPutc(*tmpfp, '-'); 113 vfpPuts(*tmpfp, ept->path); 114 vfpPutc(*tmpfp, '\n'); 115 } 116 117 if (flag || (pinfo == NULL)) 118 continue; 119 120 dbchg++; 121 122 /* 123 * If (otherstoo > 0), more than one package has an 124 * interest in the ept entry in the database. Setting 125 * ept->ftype = '\0' effectively marks the file as being 126 * "shared", thus ensuring the ept entry will not 127 * subsequently be removed. Shared editable files (ftype 128 * 'e') are a special case: they should be passed to a 129 * class action script if present. Setting ept->ftype = 130 * '^' indicates this special case of shared editable 131 * file, allowing the distinction to be made later. 132 */ 133 if (!pinfo->editflag && otherstoo) 134 ept->ftype = (ept->ftype == 'e') ? '^' : '\0'; 135 if (*pinfo->aclass) 136 (void) strcpy(ept->pkg_class, pinfo->aclass); 137 eptlist[eptnum] = ept; 138 139 ept->path = pathdup(ept->path); 140 if (ept->ainfo.local != NULL) 141 ept->ainfo.local = pathdup(ept->ainfo.local); 142 143 ept = (struct cfent *)calloc(1, sizeof (struct cfent)); 144 if ((++eptnum % EPTMALLOC) == 0) { 145 eptlist = (struct cfent **)realloc(eptlist, 146 (eptnum+EPTMALLOC)*sizeof (struct cfent *)); 147 if (eptlist == NULL) { 148 progerr(gettext(ERR_MEMORY), errno); 149 quit(99); 150 } 151 } 152 } 153 154 eptlist[eptnum] = (struct cfent *)NULL; 155 156 n = swapcfile(*pkgserver, tmpfp, pkginst, dbchg); 157 if (n == RESULT_WRN) { 158 warnflag++; 159 } else if (n == RESULT_ERR) { 160 quit(99); 161 } 162 163 return (0); 164 } 165