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 2006 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 <stdlib.h> 34 #include <unistd.h> 35 #include <string.h> 36 #include <malloc.h> 37 #include <assert.h> 38 #include <sys/stat.h> 39 #include <pkgstrct.h> 40 #include <pkginfo.h> 41 #include <locale.h> 42 #include <libintl.h> 43 #include <pkglib.h> 44 #include <install.h> 45 #include <libinst.h> 46 #include <libadm.h> 47 48 #define PINFOALLOC 200 49 50 #define ERR_MEMORY "memory allocation failure, errno=%d" 51 52 int otherstoo; 53 char *useclass; 54 55 static int pinfo_handle = -1; 56 57 /* Free all allocated package info structures. */ 58 void 59 pinfo_free(void) 60 { 61 bl_free(pinfo_handle); 62 } 63 64 /* 65 * This function manipulates the pinfo entry corresponding to the package 66 * indicated on the command line. 67 */ 68 struct pinfo * 69 eptstat(struct cfent *entry, char *pkg, char c) 70 { 71 struct pinfo *pinfo, *last, *me, *myparent; 72 73 otherstoo = 0; 74 useclass = entry->pkg_class; 75 76 me = myparent = last = (struct pinfo *)0; 77 78 if (pinfo_handle == -1) { 79 pinfo_handle = bl_create(PINFOALLOC, sizeof (struct pinfo), 80 "package data"); 81 } 82 83 for (pinfo = entry->pinfo; pinfo; pinfo = pinfo->next) { 84 if (strcmp(pkg, pinfo->pkg) == 0) { 85 if (*pinfo->aclass) 86 useclass = pinfo->aclass; 87 myparent = last; 88 me = pinfo; 89 } else 90 otherstoo++; 91 last = pinfo; 92 } 93 94 if (c) { 95 /* 96 * use a delete/add strategy to keep package list 97 * ordered by modification time 98 */ 99 if (me) { 100 /* remove from list first */ 101 if (myparent) 102 myparent->next = me->next; 103 else 104 entry->pinfo = me->next; 105 if (me == last) 106 last = myparent; 107 entry->npkgs--; 108 /* leave 'me' around until later! */ 109 } 110 if ((c != STAT_NEXT) && (me || (c != RM_RDY))) { 111 /* need to add onto end */ 112 entry->npkgs++; 113 if (me == NULL) { 114 /* LINTED pointer cast may result in impro... */ 115 me = (struct pinfo *) 116 bl_next_avail(pinfo_handle); 117 if (me == NULL) { 118 progerr(gettext(ERR_MEMORY), errno); 119 quit(99); 120 } 121 } else { 122 me->next = (struct pinfo *)NULL; 123 if (entry->npkgs == 1) { 124 if (me->aclass[0]) 125 (void) strcpy(entry->pkg_class, 126 me->aclass); 127 useclass = entry->pkg_class; 128 } else 129 useclass = me->aclass; 130 } 131 (void) strncpy(me->pkg, pkg, PKGSIZ); 132 133 /* 134 * Only change status for local objects. Need 135 * to maintain "shared" status for objects that 136 * are provided from a server. 137 */ 138 if (me->status != SERVED_FILE) 139 me->status = ((c == DUP_ENTRY) ? '\0' : c); 140 141 if (last) 142 last->next = me; /* add to end */ 143 else 144 entry->pinfo = me; /* only item */ 145 } else { 146 /* just wanted to remove this package from list */ 147 if (me) { 148 free(me); 149 me = (struct pinfo *)0; 150 } 151 } 152 } 153 return (me); 154 } 155