15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 285c51f124SMoriah Waterland /* All Rights Reserved */ 295c51f124SMoriah Waterland 305c51f124SMoriah Waterland 315c51f124SMoriah Waterland 325c51f124SMoriah Waterland #include <stdio.h> 335c51f124SMoriah Waterland #include <ctype.h> 345c51f124SMoriah Waterland #include <string.h> 355c51f124SMoriah Waterland #include <signal.h> 365c51f124SMoriah Waterland #include <errno.h> 375c51f124SMoriah Waterland #include <stdlib.h> 385c51f124SMoriah Waterland #include <valtools.h> 395c51f124SMoriah Waterland #include "pkginfo.h" 405c51f124SMoriah Waterland #include "pkglib.h" 415c51f124SMoriah Waterland #include "pkglibmsgs.h" 425c51f124SMoriah Waterland #include "pkgstrct.h" 435c51f124SMoriah Waterland #include "pkglocale.h" 445c51f124SMoriah Waterland 455c51f124SMoriah Waterland extern char *pkgdir; /* WHERE? */ 465c51f124SMoriah Waterland 475c51f124SMoriah Waterland /* libadm.a */ 485c51f124SMoriah Waterland extern CKMENU *allocmenu(char *label, int attr); 495c51f124SMoriah Waterland extern int ckitem(CKMENU *menup, char *item[], short max, char *defstr, 505c51f124SMoriah Waterland char *error, char *help, char *prompt); 515c51f124SMoriah Waterland extern int pkgnmchk(register char *pkg, register char *spec, 525c51f124SMoriah Waterland int presvr4flg); 535c51f124SMoriah Waterland extern int fpkginfo(struct pkginfo *info, char *pkginst); 545c51f124SMoriah Waterland extern char *fpkginst(char *pkg, ...); 555c51f124SMoriah Waterland extern int setinvis(CKMENU *menup, char *choice); 565c51f124SMoriah Waterland extern int setitem(CKMENU *menup, char *choice); 575c51f124SMoriah Waterland 585c51f124SMoriah Waterland #define CMDSIZ 512 595c51f124SMoriah Waterland #define LSIZE 256 605c51f124SMoriah Waterland #define MAXSIZE 128 615c51f124SMoriah Waterland #define MALLOCSIZ 128 625c51f124SMoriah Waterland #define MAX_CAT_ARGS 64 635c51f124SMoriah Waterland #define MAX_CAT_LEN 16 645c51f124SMoriah Waterland 655c51f124SMoriah Waterland static int cont_in_list = 0; /* live continuation */ 665c51f124SMoriah Waterland static char cont_keyword[PKGSIZ+1]; /* the continuation keyword */ 675c51f124SMoriah Waterland 685c51f124SMoriah Waterland /* 695c51f124SMoriah Waterland * Allocate memory for the next package name. This function attempts the 705c51f124SMoriah Waterland * allocation and if that succeeds, returns a pointer to the new memory 715c51f124SMoriah Waterland * location and increments "n". Otherwise, it returens NULL and n is 725c51f124SMoriah Waterland * unchanged. 735c51f124SMoriah Waterland */ 745c51f124SMoriah Waterland static char ** 755c51f124SMoriah Waterland next_n(int *n, char **nwpkg) 765c51f124SMoriah Waterland { 775c51f124SMoriah Waterland int loc_n = *n; 785c51f124SMoriah Waterland 795c51f124SMoriah Waterland if ((++loc_n % MALLOCSIZ) == 0) { 805c51f124SMoriah Waterland nwpkg = (char **)realloc(nwpkg, 815c51f124SMoriah Waterland (loc_n+MALLOCSIZ) * sizeof (char **)); 825c51f124SMoriah Waterland if (nwpkg == NULL) { 835c51f124SMoriah Waterland progerr(pkg_gt(ERR_MEMORY), errno); 845c51f124SMoriah Waterland errno = ENOMEM; 855c51f124SMoriah Waterland return (NULL); 865c51f124SMoriah Waterland } 875c51f124SMoriah Waterland } 885c51f124SMoriah Waterland 895c51f124SMoriah Waterland *n = loc_n; 905c51f124SMoriah Waterland return (nwpkg); 915c51f124SMoriah Waterland } 925c51f124SMoriah Waterland 935c51f124SMoriah Waterland /* 945c51f124SMoriah Waterland * This informs gpkglist() to put a keyword at the head of the pkglist. This 955c51f124SMoriah Waterland * was originally intended for live continue, but it may have other 965c51f124SMoriah Waterland * applications as well. 975c51f124SMoriah Waterland */ 985c51f124SMoriah Waterland void 995c51f124SMoriah Waterland pkglist_cont(char *keyword) 1005c51f124SMoriah Waterland { 1015c51f124SMoriah Waterland cont_in_list = 1; 1025c51f124SMoriah Waterland (void) strncpy(cont_keyword, keyword, PKGSIZ); 1035c51f124SMoriah Waterland } 1045c51f124SMoriah Waterland 1055c51f124SMoriah Waterland /* 1065c51f124SMoriah Waterland * This function constructs the list of packages that the user wants managed. 1075c51f124SMoriah Waterland * It may be a list on the command line, it may be some or all of the 1085c51f124SMoriah Waterland * packages in a directory or it may be a continuation from a previous 1095c51f124SMoriah Waterland * dryrun. It may also be a list of pkgs gathered from the CATEGORY parameter 1105c51f124SMoriah Waterland * in a spooled or installed pkginfo file. 1115c51f124SMoriah Waterland */ 1125c51f124SMoriah Waterland char ** 1135c51f124SMoriah Waterland gpkglist(char *dir, char **pkg, char **catg) 1145c51f124SMoriah Waterland { 1155c51f124SMoriah Waterland struct _choice_ *chp; 1165c51f124SMoriah Waterland struct pkginfo info; 1175c51f124SMoriah Waterland char *inst; 1185c51f124SMoriah Waterland CKMENU *menup; 1195c51f124SMoriah Waterland char temp[LSIZE]; 1205c51f124SMoriah Waterland char *savedir, **nwpkg; 1215c51f124SMoriah Waterland int i, n; 1225c51f124SMoriah Waterland 1235c51f124SMoriah Waterland savedir = pkgdir; 1245c51f124SMoriah Waterland pkgdir = dir; 1255c51f124SMoriah Waterland 1265c51f124SMoriah Waterland info.pkginst = NULL; /* initialize for memory handling */ 1275c51f124SMoriah Waterland if (pkginfo(&info, "all", NULL, NULL)) { 1285c51f124SMoriah Waterland errno = ENOPKG; /* contains no valid packages */ 1295c51f124SMoriah Waterland pkgdir = savedir; 1305c51f124SMoriah Waterland return (NULL); 1315c51f124SMoriah Waterland } 1325c51f124SMoriah Waterland 1335c51f124SMoriah Waterland /* 1345c51f124SMoriah Waterland * If no explicit list was provided and this is not a continuation 1355c51f124SMoriah Waterland * (implying a certain level of direction on the caller's part) 1365c51f124SMoriah Waterland * present a menu of available packages for installation. 1375c51f124SMoriah Waterland */ 1385c51f124SMoriah Waterland if (pkg[0] == NULL && !cont_in_list) { 1395c51f124SMoriah Waterland menup = allocmenu(pkg_gt(HEADER), CKALPHA); 1405c51f124SMoriah Waterland if (setinvis(menup, "all")) { 1415c51f124SMoriah Waterland errno = EFAULT; 1425c51f124SMoriah Waterland return (NULL); 1435c51f124SMoriah Waterland } 1445c51f124SMoriah Waterland do { 1455c51f124SMoriah Waterland /* bug id 1087404 */ 1465c51f124SMoriah Waterland if (!info.pkginst || !info.name || !info.arch || 1475c51f124SMoriah Waterland !info.version) 1485c51f124SMoriah Waterland continue; 149*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 150*4656d474SGarrett D'Amore "%s %s\n(%s) %s", info.pkginst, 1515c51f124SMoriah Waterland info.name, info.arch, info.version); 1525c51f124SMoriah Waterland if (setitem(menup, temp)) { 1535c51f124SMoriah Waterland errno = EFAULT; 1545c51f124SMoriah Waterland return (NULL); 1555c51f124SMoriah Waterland } 1565c51f124SMoriah Waterland } while (pkginfo(&info, "all", NULL, NULL) == 0); 1575c51f124SMoriah Waterland /* clear memory usage by pkginfo */ 1585c51f124SMoriah Waterland (void) pkginfo(&info, NULL, NULL, NULL); 1595c51f124SMoriah Waterland pkgdir = savedir; /* restore pkgdir to orig value */ 1605c51f124SMoriah Waterland 1615c51f124SMoriah Waterland nwpkg = (char **)calloc(MALLOCSIZ, sizeof (char **)); 1625c51f124SMoriah Waterland n = ckitem(menup, nwpkg, MALLOCSIZ, "all", NULL, 1635c51f124SMoriah Waterland pkg_gt(HELP), pkg_gt(PROMPT)); 1645c51f124SMoriah Waterland if (n) { 1655c51f124SMoriah Waterland free(nwpkg); 1665c51f124SMoriah Waterland errno = ((n == 3) ? EINTR : EFAULT); 1675c51f124SMoriah Waterland pkgdir = savedir; 1685c51f124SMoriah Waterland return (NULL); 1695c51f124SMoriah Waterland } 1705c51f124SMoriah Waterland if (strcmp(nwpkg[0], "all") == 0) { 1715c51f124SMoriah Waterland chp = menup->choice; 1725c51f124SMoriah Waterland for (n = 0; chp; /* void */) { 1735c51f124SMoriah Waterland nwpkg[n] = strdup(chp->token); 1745c51f124SMoriah Waterland nwpkg = next_n(&n, nwpkg); 1755c51f124SMoriah Waterland chp = chp->next; 1765c51f124SMoriah Waterland nwpkg[n] = NULL; 1775c51f124SMoriah Waterland } 1785c51f124SMoriah Waterland } else { 1795c51f124SMoriah Waterland for (n = 0; nwpkg[n]; n++) 1805c51f124SMoriah Waterland nwpkg[n] = strdup(nwpkg[n]); 1815c51f124SMoriah Waterland } 1825c51f124SMoriah Waterland (void) setitem(menup, NULL); /* free resources */ 1835c51f124SMoriah Waterland free(menup); 1845c51f124SMoriah Waterland pkgdir = savedir; 1855c51f124SMoriah Waterland return (nwpkg); 1865c51f124SMoriah Waterland } 1875c51f124SMoriah Waterland 1885c51f124SMoriah Waterland /* clear memory usage by pkginfo */ 1895c51f124SMoriah Waterland (void) pkginfo(&info, NULL, NULL, NULL); 1905c51f124SMoriah Waterland 1915c51f124SMoriah Waterland nwpkg = (char **)calloc(MALLOCSIZ, sizeof (char **)); 1925c51f124SMoriah Waterland 1935c51f124SMoriah Waterland /* 1945c51f124SMoriah Waterland * pkg array contains the instance identifiers to 1955c51f124SMoriah Waterland * be selected, or possibly wildcard definitions 1965c51f124SMoriah Waterland */ 1975c51f124SMoriah Waterland i = n = 0; 1985c51f124SMoriah Waterland do { 1995c51f124SMoriah Waterland if (cont_in_list) { /* This is a live continuation. */ 2005c51f124SMoriah Waterland nwpkg[n] = strdup(cont_keyword); 2015c51f124SMoriah Waterland nwpkg = next_n(&n, nwpkg); 2025c51f124SMoriah Waterland nwpkg[n] = NULL; 2035c51f124SMoriah Waterland cont_in_list = 0; /* handled */ 2045c51f124SMoriah Waterland 2055c51f124SMoriah Waterland if (pkg[0] == NULL) { /* It's just a continuation. */ 2065c51f124SMoriah Waterland break; 2075c51f124SMoriah Waterland } 2085c51f124SMoriah Waterland } else if (pkgnmchk(pkg[i], "all", 1)) { 2095c51f124SMoriah Waterland /* wildcard specification */ 2105c51f124SMoriah Waterland (void) fpkginst(NULL); 2115c51f124SMoriah Waterland inst = fpkginst(pkg[i], NULL, NULL); 2125c51f124SMoriah Waterland if (inst == NULL) { 2135c51f124SMoriah Waterland progerr(pkg_gt(ERR_NOPKG), pkg[i]); 2145c51f124SMoriah Waterland free(nwpkg); 2155c51f124SMoriah Waterland nwpkg = NULL; 2165c51f124SMoriah Waterland errno = ESRCH; 2175c51f124SMoriah Waterland break; 2185c51f124SMoriah Waterland } 2195c51f124SMoriah Waterland do { 2205c51f124SMoriah Waterland if (catg != NULL) { 2215c51f124SMoriah Waterland pkginfo(&info, inst, NULL, NULL); 2225c51f124SMoriah Waterland if (!is_same_CATEGORY(catg, 2235c51f124SMoriah Waterland info.catg)) 2245c51f124SMoriah Waterland continue; 2255c51f124SMoriah Waterland } 2265c51f124SMoriah Waterland nwpkg[n] = strdup(inst); 2275c51f124SMoriah Waterland nwpkg = next_n(&n, nwpkg); 2285c51f124SMoriah Waterland nwpkg[n] = NULL; 2295c51f124SMoriah Waterland } while (inst = fpkginst(pkg[i], NULL, NULL)); 2305c51f124SMoriah Waterland } else { 2315c51f124SMoriah Waterland if (fpkginfo(&info, pkg[i])) { 2325c51f124SMoriah Waterland progerr(pkg_gt(ERR_NOPKG), pkg[i]); 2335c51f124SMoriah Waterland free(nwpkg); 2345c51f124SMoriah Waterland nwpkg = NULL; 2355c51f124SMoriah Waterland errno = ESRCH; 2365c51f124SMoriah Waterland break; 2375c51f124SMoriah Waterland } 2385c51f124SMoriah Waterland nwpkg[n] = strdup(pkg[i]); 2395c51f124SMoriah Waterland nwpkg = next_n(&n, nwpkg); 2405c51f124SMoriah Waterland nwpkg[n] = NULL; 2415c51f124SMoriah Waterland } 2425c51f124SMoriah Waterland } while (pkg[++i]); 2435c51f124SMoriah Waterland 2445c51f124SMoriah Waterland (void) fpkginst(NULL); 2455c51f124SMoriah Waterland (void) fpkginfo(&info, NULL); 2465c51f124SMoriah Waterland pkgdir = savedir; /* restore pkgdir to orig value */ 2475c51f124SMoriah Waterland 2485c51f124SMoriah Waterland if (catg != NULL) { 2495c51f124SMoriah Waterland if (nwpkg[0] == NULL) { 2505c51f124SMoriah Waterland 2515c51f124SMoriah Waterland /* 2525c51f124SMoriah Waterland * No pkgs in the spooled directory matched the 2535c51f124SMoriah Waterland * category specified by the user. 2545c51f124SMoriah Waterland */ 2555c51f124SMoriah Waterland 2565c51f124SMoriah Waterland free(nwpkg); 2575c51f124SMoriah Waterland return (NULL); 2585c51f124SMoriah Waterland } 2595c51f124SMoriah Waterland } 2605c51f124SMoriah Waterland return (nwpkg); 2615c51f124SMoriah Waterland } 2625c51f124SMoriah Waterland 2635c51f124SMoriah Waterland /* 2645c51f124SMoriah Waterland * Check category passed in on the command line to see if it is valid. 2655c51f124SMoriah Waterland * 2665c51f124SMoriah Waterland * returns 0 if the category is valid 2675c51f124SMoriah Waterland * returns 1 if the category is invalid 2685c51f124SMoriah Waterland */ 2695c51f124SMoriah Waterland 2705c51f124SMoriah Waterland int 2715c51f124SMoriah Waterland is_not_valid_category(char **category, char *progname) 2725c51f124SMoriah Waterland { 2735c51f124SMoriah Waterland if (strcasecmp(progname, "pkgrm") == 0) { 2745c51f124SMoriah Waterland if (is_same_CATEGORY(category, "system")) 2755c51f124SMoriah Waterland return (1); 2765c51f124SMoriah Waterland } 2775c51f124SMoriah Waterland 2785c51f124SMoriah Waterland return (0); 2795c51f124SMoriah Waterland } 2805c51f124SMoriah Waterland 2815c51f124SMoriah Waterland /* 2825c51f124SMoriah Waterland * Check category length 2835c51f124SMoriah Waterland * 2845c51f124SMoriah Waterland * returns 0 if the category length is valid 2855c51f124SMoriah Waterland * returns 1 if a category has length > 16 chars as defined by the SVr4 ABI 2865c51f124SMoriah Waterland */ 2875c51f124SMoriah Waterland 2885c51f124SMoriah Waterland int 2895c51f124SMoriah Waterland is_not_valid_length(char **category) 2905c51f124SMoriah Waterland { 2915c51f124SMoriah Waterland int i; 2925c51f124SMoriah Waterland 2935c51f124SMoriah Waterland for (i = 0; category[i] != NULL; i++) { 2945c51f124SMoriah Waterland if (strlen(category[i]) > MAX_CAT_LEN) 2955c51f124SMoriah Waterland return (1); 2965c51f124SMoriah Waterland } 2975c51f124SMoriah Waterland 2985c51f124SMoriah Waterland return (0); 2995c51f124SMoriah Waterland } 3005c51f124SMoriah Waterland 3015c51f124SMoriah Waterland /* 3025c51f124SMoriah Waterland * Check category passed in on the command line against the CATEGORY in the 3035c51f124SMoriah Waterland * spooled or installed packages pkginfo file. 3045c51f124SMoriah Waterland * 3055c51f124SMoriah Waterland * returns 0 if categories match 3065c51f124SMoriah Waterland * returns 1 if categories don't match 3075c51f124SMoriah Waterland */ 3085c51f124SMoriah Waterland 3095c51f124SMoriah Waterland int 3105c51f124SMoriah Waterland is_same_CATEGORY(char **category, char *persistent_category) 3115c51f124SMoriah Waterland { 3125c51f124SMoriah Waterland int i, j, n = 0; 3135c51f124SMoriah Waterland char *pers_catg, **pers_catgs; 3145c51f124SMoriah Waterland 3155c51f124SMoriah Waterland pers_catg = strdup(persistent_category); 3165c51f124SMoriah Waterland 3175c51f124SMoriah Waterland pers_catgs = (char **)calloc(MAX_CAT_LEN, sizeof (char **)); 3185c51f124SMoriah Waterland 3195c51f124SMoriah Waterland pers_catgs[n++] = strtok(pers_catg, " \t\n, "); 3205c51f124SMoriah Waterland while (pers_catgs[n] = strtok(NULL, " \t\n, ")) 3215c51f124SMoriah Waterland n++; 3225c51f124SMoriah Waterland 3235c51f124SMoriah Waterland for (i = 0; category[i] != NULL; i++) { 3245c51f124SMoriah Waterland for (j = 0; j < n; j++) { 3255c51f124SMoriah Waterland if (strcasecmp(category[i], pers_catgs[j]) == 0) { 3265c51f124SMoriah Waterland return (1); 3275c51f124SMoriah Waterland } 3285c51f124SMoriah Waterland } 3295c51f124SMoriah Waterland } 3305c51f124SMoriah Waterland 3315c51f124SMoriah Waterland return (0); 3325c51f124SMoriah Waterland } 3335c51f124SMoriah Waterland 3345c51f124SMoriah Waterland /* 3355c51f124SMoriah Waterland * Given a string of categories, construct a null-terminated array of 3365c51f124SMoriah Waterland * categories. 3375c51f124SMoriah Waterland * 3385c51f124SMoriah Waterland * returns the array of categories or NULL 3395c51f124SMoriah Waterland */ 3405c51f124SMoriah Waterland 3415c51f124SMoriah Waterland char ** 3425c51f124SMoriah Waterland get_categories(char *catg_arg) 3435c51f124SMoriah Waterland { 3445c51f124SMoriah Waterland int n = 0; 3455c51f124SMoriah Waterland char *tmp_catg; 3465c51f124SMoriah Waterland char **catgs; 3475c51f124SMoriah Waterland 3485c51f124SMoriah Waterland tmp_catg = strdup(catg_arg); 3495c51f124SMoriah Waterland 3505c51f124SMoriah Waterland catgs = (char **)calloc(MAX_CAT_LEN, sizeof (char **)); 3515c51f124SMoriah Waterland 3525c51f124SMoriah Waterland catgs[n++] = strtok(tmp_catg, " \t\n, "); 3535c51f124SMoriah Waterland while (catgs[n] = strtok(NULL, " \t\n, ")) 3545c51f124SMoriah Waterland n++; 3555c51f124SMoriah Waterland 3565c51f124SMoriah Waterland if (*catgs == NULL) 3575c51f124SMoriah Waterland return (NULL); 3585c51f124SMoriah Waterland else 3595c51f124SMoriah Waterland return (catgs); 3605c51f124SMoriah Waterland } 361