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 *
cl_iscript(int idx)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
cl_deliscript(int idx)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 *
cl_rscript(int idx)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
find_CAS(int CAS_type,char * pkgbin,char * instdir)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
is_WOS_arch(void)194 is_WOS_arch(void)
195 {
196 	pkg_has_arch++;
197 }
198