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]
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 */
45 static int cl_handle
= -1; /* list array handle */
47 struct cl_attr
**cl_Classes
= NULL
;
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
);
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
),
66 if (cl_handle
== -1) {
67 progerr(gettext(ERR_MEMORY
));
72 class_ptr
= (struct cl_attr
**)ar_next_avail(cl_handle
);
74 if (class_ptr
== NULL
|| *class_ptr
== NULL
) {
75 progerr(gettext(ERR_MEMORY
));
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
);
91 /* Insert a single class into the list. */
93 addlist(struct cl_attr
***listp
, char *item
)
97 /* If the list is already there, scan for this item */
99 for (i
= 0; (*listp
)[i
]; i
++)
100 if (strcmp(item
, (*listp
)[i
]->name
) == 0)
106 /* Insert the new entry */
107 if (new_cl_attr(item
) == NULL
)
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
119 setlist(struct cl_attr
***plist
, char *slist
)
121 struct cl_attr
**list
, *struct_ptr
;
127 /* Initialize the environment scanners. */
128 (void) s_verify(NULL
);
129 (void) d_verify(NULL
);
130 (void) s_pathtype(NULL
);
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");
147 if (sn
== -1 && strcmp(pt
, "none") == 0)
150 /* Add new class to list. */
151 if ((struct_ptr
= new_cl_attr(pt
)) == NULL
)
156 pt
= strtok(NULL
, " \t\n");
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!
169 /* Get the head of the array. */
170 list
= (struct cl_attr
**)ar_get_head(cl_handle
);
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. */
186 /* Process the class list from the caller. */
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
);
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.
216 cl_putl(char *parm_name
, struct cl_attr
**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
);
244 for (n
= 0; n
< cl_NClasses
; n
++)
245 if (strcmp(cl_Classes
[n
]->name
, cl_nam
) == 0)
250 /* Return source verification level for this class */
254 if (cl_Classes
&& idx
>= 0 && idx
< cl_NClasses
)
255 return (cl_Classes
[idx
]->src_verify
);
259 /* Return destination verify level for this class */
263 if (cl_Classes
&& idx
>= 0 && idx
< cl_NClasses
)
264 return (cl_Classes
[idx
]->dst_verify
);
268 /* Return path argument type for this class. */
272 if (cl_Classes
&& idx
>= 0 && idx
< cl_NClasses
)
273 return (cl_Classes
[idx
]->relpath_2_CAS
);
277 /* Return the class name associated with this class index */
281 if (cl_Classes
&& idx
>= 0 && idx
< cl_NClasses
)
282 return (cl_Classes
[idx
]->name
);
287 cl_setl(struct cl_attr
**cl_lst
)
294 for (cl_NClasses
= 0; cl_lst
[cl_NClasses
]; cl_NClasses
++)
295 if (strcmp(cl_lst
[cl_NClasses
]->name
, "none") == 0)
300 for (i
= sn
; i
> 0; i
--)
301 cl_lst
[i
] = cl_lst
[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];
319 * Scan the given environment variable for an occurrance of the given
320 * class name. Return 0 if not found or 1 if found.
323 is_in_env(char *class_name
, char *paramname
, char **paramvalue
, int *noentry
)
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
334 if (!(*noentry
) && *paramvalue
== NULL
) {
335 *paramvalue
= getenv(paramname
);
336 if (*paramvalue
== NULL
)
340 /* If there's something there, evaluate it. */
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') {
360 if (*(++test_class
) == '\0')
368 /* Assign source path verification level to this class */
370 s_verify(char *class_name
)
373 static char *noverify
;
375 if (class_name
== NULL
) { /* initialize */
379 if (is_in_env(class_name
, "PKG_SRC_NOVERIFY", &noverify
,
389 * Set destination verify to default. This is usually called by pkgdbmerg()
390 * in order to correct verification conflicts.
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. */
401 d_verify(char *class_name
)
404 static char *qkverify
;
406 if (class_name
== NULL
) { /* initialize */
410 if (is_in_env(class_name
, "PKG_DST_QKVERIFY", &qkverify
,
419 /* Assign CAS path type to this class */
421 s_pathtype(char *class_name
)
424 static char *type_list
;
426 if (class_name
== NULL
) { /* initialize */
430 if (is_in_env(class_name
, "PKG_CAS_PASSRELATIVE", &type_list
,