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 1995 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 29 #include <stdio.h> 30 #include <errno.h> 31 #include <string.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include <locale.h> 35 #include <libintl.h> 36 #include <pkglocs.h> 37 #include <pkglib.h> 38 #include "libinst.h" 39 40 #define ERR_INVALID_CAS "%d is an invalid class action script type." 41 #define ERR_NO_NONE "Cannot find the default archive install script." 42 #define ERR_NO_PATH "No paths for finding class action scripts." 43 44 /* setlist.c */ 45 extern struct cl_attr **cl_Classes; 46 extern int cl_NClasses; 47 extern char *cl_nam(int idx); 48 49 static int pkg_has_arch; 50 51 /* Return the install class action script associated with this class index */ 52 char * 53 cl_iscript(int idx) 54 { 55 if (cl_Classes && idx >= 0 && idx < cl_NClasses) 56 return (cl_Classes[idx]->inst_script); 57 return (NULL); 58 } 59 60 /* 61 * This resets an input class action script pointer and the various 62 * codes that are associated with special treatment available to a class 63 * action script. It returns 1 if there was a script there in the first 64 * place and 0 if there wasn't. 65 */ 66 int 67 cl_deliscript(int idx) 68 { 69 if (cl_Classes && idx >= 0 && idx < cl_NClasses) 70 if (cl_Classes[idx]->inst_script) { 71 free(cl_Classes[idx]->inst_script); 72 cl_Classes[idx]->inst_script = NULL; 73 cl_Classes[idx]->src_verify = DEFAULT; 74 cl_Classes[idx]->dst_verify = DEFAULT; 75 cl_Classes[idx]->relpath_2_CAS = DEFAULT; 76 77 } else 78 return (0); 79 return (1); 80 } 81 82 /* Return the remove class action script associated with this class index */ 83 char * 84 cl_rscript(int idx) 85 { 86 if (cl_Classes && idx >= 0 && idx < cl_NClasses) 87 return (cl_Classes[idx]->rem_script); 88 return (NULL); 89 } 90 91 /* 92 * This scans the admin directories for the class acton scripts associated 93 * with the classes to be installed. It will look for install or remove 94 * scripts and place appropriate pointers into the cl_Classes list. There's 95 * no reason why it couldn't look for both except that I haven't seen a 96 * need for it yet. 97 */ 98 void 99 find_CAS(int CAS_type, char *pkgbin, char *instdir) 100 { 101 int i; 102 char path[PATH_MAX]; 103 104 if (instdir == NULL || pkgbin == NULL) { 105 progerr(gettext(ERR_NO_PATH)); 106 quit(99); 107 } 108 109 if (CAS_type == I_ONLY) { 110 for (i = 0; i < cl_NClasses; i++) { 111 /* 112 * Locate appropriate installation class action 113 * script, if any; look on media for script, 114 * since it might be on the system due to a 115 * previous installation. 116 */ 117 (void) sprintf(path, "%s/install/i.%s", instdir, 118 cl_nam(i)); 119 if (access(path, R_OK) == 0) { 120 (void) sprintf(path, "%s/i.%s", pkgbin, 121 cl_nam(i)); 122 cl_Classes[i]->inst_script = qstrdup(path); 123 continue; 124 } 125 126 (void) sprintf(path, "%s/i.%s", PKGSCR, cl_nam(i)); 127 if (access(path, R_OK) == 0) { 128 cl_Classes[i]->inst_script = qstrdup(path); 129 continue; 130 } 131 132 /* 133 * Provide CAS to uncompress and distribute a 134 * compressed cpio archive for those older packages 135 * that don't include their own. This is the first 136 * point at which we know, it's an old package 137 * without all the various pkginfo items set. 138 * The default script is provided for all classes 139 * in an old package which do not have their own 140 * class action script. These are the criteria used 141 * by the script that packs the archives. 142 */ 143 (void) sprintf(path, "%s/%s", PKGSCR, DEF_NONE_SCR); 144 if (pkg_has_arch && 145 cl_Classes[i]->inst_script == NULL) { 146 147 cl_Classes[i]->src_verify = NOVERIFY; 148 cl_Classes[i]->dst_verify = QKVERIFY; 149 cl_Classes[i]->relpath_2_CAS = REL_2_CAS; 150 151 if (access(path, R_OK) == 0) { 152 cl_Classes[i]->inst_script = 153 qstrdup(path); 154 continue; 155 } else { 156 progerr(gettext(ERR_NO_NONE)); 157 quit(99); 158 } 159 160 } 161 } 162 } else if (CAS_type == R_ONLY) { 163 for (i = 0; i < cl_NClasses; i++) { 164 (void) sprintf(path, "%s/install/r.%s", instdir, 165 cl_nam(i)); 166 if (access(path, R_OK) == 0) { 167 (void) sprintf(path, "%s/r.%s", pkgbin, 168 cl_nam(i)); 169 cl_Classes[i]->rem_script = qstrdup(path); 170 continue; 171 } 172 173 (void) sprintf(path, "%s/r.%s", PKGSCR, cl_nam(i)); 174 if (access(path, R_OK) == 0) { 175 cl_Classes[i]->rem_script = qstrdup(path); 176 continue; 177 } 178 } 179 } else { 180 progerr(gettext(ERR_INVALID_CAS), CAS_type); 181 quit(99); 182 } 183 } 184 185 /* 186 * This function deals with the special case of an old WOS package 187 * with a compressed cpio'd file set but no class action script. 188 * We find out it doesn't have a CAS later in find_CAS() and deal 189 * with it then. The only reason for this variable is to let 190 * findscripts() know to get the default script if it can't find it in 191 * the usual places. 192 */ 193 void 194 is_WOS_arch(void) 195 { 196 pkg_has_arch++; 197 } 198