8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / cmd / svr4pkg / libinst / setlist.c
blob31fd9f17f12856bc380f257c4b825d8a1ea869a1
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
32 #include <stdio.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <locale.h>
39 #include <libintl.h>
40 #include <pkglocs.h>
41 #include <pkglib.h>
42 #include "libinst.h"
44 int cl_NClasses = -1;
45 static int cl_handle = -1; /* list array handle */
47 struct cl_attr **cl_Classes = NULL;
49 static int new_order;
50 static struct cl_attr *new_cl_attr(char *cl_name);
52 static unsigned s_verify(char *class_name), d_verify(char *class_name);
53 static unsigned s_pathtype(char *class_name);
55 #define MALSIZ 64
56 #define ERR_MEMORY "memory allocation failure"
58 static struct cl_attr *
59 new_cl_attr(char *cl_name)
61 struct cl_attr *class, **class_ptr;
63 if (cl_handle == -1) {
64 cl_handle = ar_create(MALSIZ, sizeof (struct cl_attr),
65 "package class");
66 if (cl_handle == -1) {
67 progerr(gettext(ERR_MEMORY));
68 return (NULL);
72 class_ptr = (struct cl_attr **)ar_next_avail(cl_handle);
74 if (class_ptr == NULL || *class_ptr == NULL) {
75 progerr(gettext(ERR_MEMORY));
76 return (NULL);
79 class = *class_ptr;
81 strcpy(class->name, cl_name);
82 class->inst_script = NULL;
83 class->rem_script = NULL;
84 class->src_verify = s_verify(cl_name);
85 class->dst_verify = d_verify(cl_name);
86 class->relpath_2_CAS = s_pathtype(cl_name);
88 return (class);
91 /* Insert a single class into the list. */
92 void
93 addlist(struct cl_attr ***listp, char *item)
95 int i;
97 /* If the list is already there, scan for this item */
98 if (*listp) {
99 for (i = 0; (*listp)[i]; i++)
100 if (strcmp(item, (*listp)[i]->name) == 0)
101 return;
102 } else {
103 i = 0;
106 /* Insert the new entry */
107 if (new_cl_attr(item) == NULL)
108 quit(99);
110 /* Point the passed pointer to the head of the list. */
111 (*listp) = (struct cl_attr **)ar_get_head(cl_handle);
115 * Create a list of all classes involved in this installation as well as
116 * their attributes.
119 setlist(struct cl_attr ***plist, char *slist)
121 struct cl_attr **list, *struct_ptr;
122 char *pt;
123 int n;
124 int i;
125 int sn = -1;
127 /* Initialize the environment scanners. */
128 (void) s_verify(NULL);
129 (void) d_verify(NULL);
130 (void) s_pathtype(NULL);
132 n = 0;
135 * This looks like a serious memory leak, however pkgmk depends on
136 * this creating a second list and forgetting any prior ones. The
137 * pkgmk utility does a reasonable job of keeping track of a prior
138 * list constructed from the prototype file using addlist() above.
139 * Perhaps this should be reviewed later, but I do not believe this
140 * to be a problem from what I've seen. - JST
142 cl_handle = -1; /* forget other lists */
144 /* Isolate the first token. */
145 pt = strtok(slist, " \t\n");
146 while (pt) {
147 if (sn == -1 && strcmp(pt, "none") == 0)
148 sn = n;
150 /* Add new class to list. */
151 if ((struct_ptr = new_cl_attr(pt)) == NULL)
152 quit(99);
154 /* Next token. */
155 n++;
156 pt = strtok(NULL, " \t\n");
157 if (pt && sn != -1)
158 if (strcmp(pt, "none") == 0)
159 pt = strtok(NULL, " \t\n");
162 * According to the ABI, if there is a class "none", it will be
163 * the first class to be installed. This insures that iff there
164 * is a class "none", it will be the first to be installed.
165 * If there is no class "none", nothing happens!
167 new_order = 0;
169 /* Get the head of the array. */
170 list = (struct cl_attr **)ar_get_head(cl_handle);
172 if (sn > 0) {
173 struct_ptr = list[sn];
174 for (i = sn; i > 0; i--)
175 list[i] = list[i - 1];
176 list[0] = struct_ptr;
177 new_order++; /* the order is different now */
180 /* Point the passed pointer to the head of the list. */
181 *plist = list;
183 return (n);
186 /* Process the class list from the caller. */
187 void
188 cl_sets(char *slist)
190 char *list_ptr;
192 /* If there is a list, process it; else skip it */
193 if (slist && *slist) {
194 list_ptr = qstrdup(slist);
196 if (list_ptr && *list_ptr) {
197 cl_NClasses = setlist(&cl_Classes, list_ptr);
198 if (new_order) /* if list order changed ... */
199 /* ... tell the environment. */
200 cl_putl("CLASSES", cl_Classes);
206 cl_getn(void)
208 return (cl_NClasses);
212 * Since the order may have changed, this puts the CLASSES list back into
213 * the environment in the precise order to be used.
215 void
216 cl_putl(char *parm_name, struct cl_attr **list)
218 int i;
219 size_t j;
220 char *pt = NULL;
222 if (list && *list) {
223 j = 1; /* room for ending null */
224 for (i = 0; list[i]; i++)
225 j += strlen(list[i]->name) + 1;
226 pt = calloc(j, sizeof (char));
227 (void) strcpy(pt, list[0]->name);
228 for (i = 1; list[i]; i++) {
229 (void) strcat(pt, " ");
230 (void) strcat(pt, list[i]->name);
232 if (parm_name && *parm_name)
233 putparam(parm_name, pt);
234 free(pt);
240 cl_idx(char *cl_nam)
242 int n;
244 for (n = 0; n < cl_NClasses; n++)
245 if (strcmp(cl_Classes[n]->name, cl_nam) == 0)
246 return (n);
247 return (-1);
250 /* Return source verification level for this class */
251 unsigned
252 cl_svfy(int idx)
254 if (cl_Classes && idx >= 0 && idx < cl_NClasses)
255 return (cl_Classes[idx]->src_verify);
256 return (0);
259 /* Return destination verify level for this class */
260 unsigned
261 cl_dvfy(int idx)
263 if (cl_Classes && idx >= 0 && idx < cl_NClasses)
264 return (cl_Classes[idx]->dst_verify);
265 return (0);
268 /* Return path argument type for this class. */
269 unsigned
270 cl_pthrel(int idx)
272 if (cl_Classes && idx >= 0 && idx < cl_NClasses)
273 return (cl_Classes[idx]->relpath_2_CAS);
274 return (0);
277 /* Return the class name associated with this class index */
278 char *
279 cl_nam(int idx)
281 if (cl_Classes && idx >= 0 && idx < cl_NClasses)
282 return (cl_Classes[idx]->name);
283 return (NULL);
286 void
287 cl_setl(struct cl_attr **cl_lst)
289 int i;
290 int sn = -1;
291 struct cl_attr *pt;
293 if (cl_lst) {
294 for (cl_NClasses = 0; cl_lst[cl_NClasses]; cl_NClasses++)
295 if (strcmp(cl_lst[cl_NClasses]->name, "none") == 0)
296 if (sn == -1)
297 sn = cl_NClasses;
298 if (sn > 0) {
299 pt = cl_lst[sn];
300 for (i = sn; i > 0; i--)
301 cl_lst[i] = cl_lst[i - 1];
302 cl_lst[0] = pt;
304 i = 1;
305 while (i < cl_NClasses) {
306 if (strcmp(cl_lst[i]->name, "none") == 0)
307 for (sn = i; sn < (cl_NClasses - 1); sn++)
308 cl_lst[sn] = cl_lst[sn + 1];
309 i++;
311 cl_Classes = cl_lst;
312 } else {
313 cl_Classes = NULL;
314 cl_NClasses = -1;
319 * Scan the given environment variable for an occurrance of the given
320 * class name. Return 0 if not found or 1 if found.
322 static unsigned
323 is_in_env(char *class_name, char *paramname, char **paramvalue, int *noentry)
325 unsigned retval = 0;
326 char *test_class;
328 if (class_name && *class_name) {
330 * If a prior getenv() has not failed and there is no
331 * environment string then get environment info on
332 * this parameter.
334 if (!(*noentry) && *paramvalue == NULL) {
335 *paramvalue = getenv(paramname);
336 if (*paramvalue == NULL)
337 (*noentry)++;
340 /* If there's something there, evaluate it. */
341 if (!(*noentry)) {
342 int n;
344 n = strlen(class_name); /* end of class name */
345 test_class = *paramvalue; /* environ ptr */
347 while (test_class = strstr(test_class, class_name)) {
349 * At this point we have a pointer to a
350 * substring within param that matches
351 * class_name for its length, but class_name
352 * may be a substring of the test_class, so
353 * we check that next.
355 if (isspace(*(test_class + n)) ||
356 *(test_class + n) == '\0') {
357 retval = 1;
358 break;
360 if (*(++test_class) == '\0')
361 break;
365 return (retval);
368 /* Assign source path verification level to this class */
369 static unsigned
370 s_verify(char *class_name)
372 static int noentry;
373 static char *noverify;
375 if (class_name == NULL) { /* initialize */
376 noentry = 0;
377 noverify = NULL;
378 } else {
379 if (is_in_env(class_name, "PKG_SRC_NOVERIFY", &noverify,
380 &noentry))
381 return (NOVERIFY);
382 else
383 return (DEFAULT);
385 return (0);
389 * Set destination verify to default. This is usually called by pkgdbmerg()
390 * in order to correct verification conflicts.
392 void
393 cl_def_dverify(int idx)
395 if (cl_Classes && idx >= 0 && idx < cl_NClasses)
396 cl_Classes[idx]->dst_verify = DEFAULT;
399 /* Assign destination path verification level to this path. */
400 static unsigned
401 d_verify(char *class_name)
403 static int noentry;
404 static char *qkverify;
406 if (class_name == NULL) { /* initialize */
407 noentry = 0;
408 qkverify = NULL;
409 } else {
410 if (is_in_env(class_name, "PKG_DST_QKVERIFY", &qkverify,
411 &noentry))
412 return (QKVERIFY);
413 else
414 return (DEFAULT);
416 return (0);
419 /* Assign CAS path type to this class */
420 static unsigned
421 s_pathtype(char *class_name)
423 static int noentry;
424 static char *type_list;
426 if (class_name == NULL) { /* initialize */
427 noentry = 0;
428 type_list = NULL;
429 } else {
430 if (is_in_env(class_name, "PKG_CAS_PASSRELATIVE", &type_list,
431 &noentry))
432 return (REL_2_CAS);
433 else
434 return (DEFAULT);
436 return (0);