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 2009 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 */
41 #include "pkglibmsgs.h"
43 #include "pkglocale.h"
45 extern char *pkgdir
; /* WHERE? */
48 extern CKMENU
*allocmenu(char *label
, int attr
);
49 extern int ckitem(CKMENU
*menup
, char *item
[], short max
, char *defstr
,
50 char *error
, char *help
, char *prompt
);
51 extern int pkgnmchk(register char *pkg
, register char *spec
,
53 extern int fpkginfo(struct pkginfo
*info
, char *pkginst
);
54 extern char *fpkginst(char *pkg
, ...);
55 extern int setinvis(CKMENU
*menup
, char *choice
);
56 extern int setitem(CKMENU
*menup
, char *choice
);
62 #define MAX_CAT_ARGS 64
63 #define MAX_CAT_LEN 16
65 static int cont_in_list
= 0; /* live continuation */
66 static char cont_keyword
[PKGSIZ
+1]; /* the continuation keyword */
69 * Allocate memory for the next package name. This function attempts the
70 * allocation and if that succeeds, returns a pointer to the new memory
71 * location and increments "n". Otherwise, it returens NULL and n is
75 next_n(int *n
, char **nwpkg
)
79 if ((++loc_n
% MALLOCSIZ
) == 0) {
80 nwpkg
= (char **)realloc(nwpkg
,
81 (loc_n
+MALLOCSIZ
) * sizeof (char **));
83 progerr(pkg_gt(ERR_MEMORY
), errno
);
94 * This informs gpkglist() to put a keyword at the head of the pkglist. This
95 * was originally intended for live continue, but it may have other
96 * applications as well.
99 pkglist_cont(char *keyword
)
102 (void) strncpy(cont_keyword
, keyword
, PKGSIZ
);
106 * This function constructs the list of packages that the user wants managed.
107 * It may be a list on the command line, it may be some or all of the
108 * packages in a directory or it may be a continuation from a previous
109 * dryrun. It may also be a list of pkgs gathered from the CATEGORY parameter
110 * in a spooled or installed pkginfo file.
113 gpkglist(char *dir
, char **pkg
, char **catg
)
115 struct _choice_
*chp
;
120 char *savedir
, **nwpkg
;
126 info
.pkginst
= NULL
; /* initialize for memory handling */
127 if (pkginfo(&info
, "all", NULL
, NULL
)) {
128 errno
= ENOPKG
; /* contains no valid packages */
134 * If no explicit list was provided and this is not a continuation
135 * (implying a certain level of direction on the caller's part)
136 * present a menu of available packages for installation.
138 if (pkg
[0] == NULL
&& !cont_in_list
) {
139 menup
= allocmenu(pkg_gt(HEADER
), CKALPHA
);
140 if (setinvis(menup
, "all")) {
146 if (!info
.pkginst
|| !info
.name
|| !info
.arch
||
149 (void) snprintf(temp
, sizeof (temp
),
150 "%s %s\n(%s) %s", info
.pkginst
,
151 info
.name
, info
.arch
, info
.version
);
152 if (setitem(menup
, temp
)) {
156 } while (pkginfo(&info
, "all", NULL
, NULL
) == 0);
157 /* clear memory usage by pkginfo */
158 (void) pkginfo(&info
, NULL
, NULL
, NULL
);
159 pkgdir
= savedir
; /* restore pkgdir to orig value */
161 nwpkg
= (char **)calloc(MALLOCSIZ
, sizeof (char **));
162 n
= ckitem(menup
, nwpkg
, MALLOCSIZ
, "all", NULL
,
163 pkg_gt(HELP
), pkg_gt(PROMPT
));
166 errno
= ((n
== 3) ? EINTR
: EFAULT
);
170 if (strcmp(nwpkg
[0], "all") == 0) {
172 for (n
= 0; chp
; /* void */) {
173 nwpkg
[n
] = strdup(chp
->token
);
174 nwpkg
= next_n(&n
, nwpkg
);
179 for (n
= 0; nwpkg
[n
]; n
++)
180 nwpkg
[n
] = strdup(nwpkg
[n
]);
182 (void) setitem(menup
, NULL
); /* free resources */
188 /* clear memory usage by pkginfo */
189 (void) pkginfo(&info
, NULL
, NULL
, NULL
);
191 nwpkg
= (char **)calloc(MALLOCSIZ
, sizeof (char **));
194 * pkg array contains the instance identifiers to
195 * be selected, or possibly wildcard definitions
199 if (cont_in_list
) { /* This is a live continuation. */
200 nwpkg
[n
] = strdup(cont_keyword
);
201 nwpkg
= next_n(&n
, nwpkg
);
203 cont_in_list
= 0; /* handled */
205 if (pkg
[0] == NULL
) { /* It's just a continuation. */
208 } else if (pkgnmchk(pkg
[i
], "all", 1)) {
209 /* wildcard specification */
210 (void) fpkginst(NULL
);
211 inst
= fpkginst(pkg
[i
], NULL
, NULL
);
213 progerr(pkg_gt(ERR_NOPKG
), pkg
[i
]);
221 pkginfo(&info
, inst
, NULL
, NULL
);
222 if (!is_same_CATEGORY(catg
,
226 nwpkg
[n
] = strdup(inst
);
227 nwpkg
= next_n(&n
, nwpkg
);
229 } while (inst
= fpkginst(pkg
[i
], NULL
, NULL
));
231 if (fpkginfo(&info
, pkg
[i
])) {
232 progerr(pkg_gt(ERR_NOPKG
), pkg
[i
]);
238 nwpkg
[n
] = strdup(pkg
[i
]);
239 nwpkg
= next_n(&n
, nwpkg
);
244 (void) fpkginst(NULL
);
245 (void) fpkginfo(&info
, NULL
);
246 pkgdir
= savedir
; /* restore pkgdir to orig value */
249 if (nwpkg
[0] == NULL
) {
252 * No pkgs in the spooled directory matched the
253 * category specified by the user.
264 * Check category passed in on the command line to see if it is valid.
266 * returns 0 if the category is valid
267 * returns 1 if the category is invalid
271 is_not_valid_category(char **category
, char *progname
)
273 if (strcasecmp(progname
, "pkgrm") == 0) {
274 if (is_same_CATEGORY(category
, "system"))
282 * Check category length
284 * returns 0 if the category length is valid
285 * returns 1 if a category has length > 16 chars as defined by the SVr4 ABI
289 is_not_valid_length(char **category
)
293 for (i
= 0; category
[i
] != NULL
; i
++) {
294 if (strlen(category
[i
]) > MAX_CAT_LEN
)
302 * Check category passed in on the command line against the CATEGORY in the
303 * spooled or installed packages pkginfo file.
305 * returns 0 if categories match
306 * returns 1 if categories don't match
310 is_same_CATEGORY(char **category
, char *persistent_category
)
313 char *pers_catg
, **pers_catgs
;
315 pers_catg
= strdup(persistent_category
);
317 pers_catgs
= (char **)calloc(MAX_CAT_LEN
, sizeof (char **));
319 pers_catgs
[n
++] = strtok(pers_catg
, " \t\n, ");
320 while (pers_catgs
[n
] = strtok(NULL
, " \t\n, "))
323 for (i
= 0; category
[i
] != NULL
; i
++) {
324 for (j
= 0; j
< n
; j
++) {
325 if (strcasecmp(category
[i
], pers_catgs
[j
]) == 0) {
335 * Given a string of categories, construct a null-terminated array of
338 * returns the array of categories or NULL
342 get_categories(char *catg_arg
)
348 tmp_catg
= strdup(catg_arg
);
350 catgs
= (char **)calloc(MAX_CAT_LEN
, sizeof (char **));
352 catgs
[n
++] = strtok(tmp_catg
, " \t\n, ");
353 while (catgs
[n
] = strtok(NULL
, " \t\n, "))