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 2006 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 #include <stdio.h>
325c51f124SMoriah Waterland #include <string.h>
335c51f124SMoriah Waterland #include <stdlib.h>
345c51f124SMoriah Waterland #include <unistd.h>
355c51f124SMoriah Waterland #include <valtools.h>
365c51f124SMoriah Waterland #include <locale.h>
375c51f124SMoriah Waterland #include <libintl.h>
385c51f124SMoriah Waterland #include <pkginfo.h>
395c51f124SMoriah Waterland #include "install.h"
405c51f124SMoriah Waterland #include <pkglib.h>
415c51f124SMoriah Waterland #include "libadm.h"
425c51f124SMoriah Waterland #include "libinst.h"
435c51f124SMoriah Waterland #include "pkginstall.h"
445c51f124SMoriah Waterland #include "messages.h"
455c51f124SMoriah Waterland
465c51f124SMoriah Waterland extern struct admin adm;
475c51f124SMoriah Waterland extern char *pkgarch, *pkgvers, *msgtext, *pkgabrv;
48*9ab815e1SGarrett D'Amore extern int maxinst;
495c51f124SMoriah Waterland
505c51f124SMoriah Waterland static char newinst[PKGSIZ];
515c51f124SMoriah Waterland static char *nextinst(void);
525c51f124SMoriah Waterland static char *prompt(struct pkginfo *info, int npkgs);
535c51f124SMoriah Waterland static int same_pkg; /* same PKG, ARCH and VERSION */
545c51f124SMoriah Waterland
555c51f124SMoriah Waterland /*
565c51f124SMoriah Waterland * This returns the correct package instance based on how many packages are
575c51f124SMoriah Waterland * already installed. If there are none (npkgs == 0), it just returns the
585c51f124SMoriah Waterland * package abbreviation. Otherwise, it interacts with the user (or reads the
595c51f124SMoriah Waterland * admin file) to determine if we should overwrite an instance which is
605c51f124SMoriah Waterland * already installed, or possibly install a new instance of this package
615c51f124SMoriah Waterland */
625c51f124SMoriah Waterland char *
getinst(int * updatingExisting,struct pkginfo * info,int npkgs,boolean_t a_preinstallCheck)635c51f124SMoriah Waterland getinst(int *updatingExisting, struct pkginfo *info, int npkgs,
645c51f124SMoriah Waterland boolean_t a_preinstallCheck)
655c51f124SMoriah Waterland {
665c51f124SMoriah Waterland char *inst;
675c51f124SMoriah Waterland char *sameinst;
685c51f124SMoriah Waterland int i;
695c51f124SMoriah Waterland int nsamearch;
705c51f124SMoriah Waterland int samearch;
715c51f124SMoriah Waterland
725c51f124SMoriah Waterland /* entry debugging info */
735c51f124SMoriah Waterland
745c51f124SMoriah Waterland same_pkg = 0;
755c51f124SMoriah Waterland
765c51f124SMoriah Waterland /*
775c51f124SMoriah Waterland * If this is the first instance of the package, it's called the by
785c51f124SMoriah Waterland * the package abbreviation.
795c51f124SMoriah Waterland */
805c51f124SMoriah Waterland
815c51f124SMoriah Waterland if (npkgs == 0) {
825c51f124SMoriah Waterland return (pkgabrv);
835c51f124SMoriah Waterland }
845c51f124SMoriah Waterland
855c51f124SMoriah Waterland /*
865c51f124SMoriah Waterland * this package is already installed; determine how to handle the
875c51f124SMoriah Waterland * new instance of the package to install
885c51f124SMoriah Waterland */
895c51f124SMoriah Waterland
905c51f124SMoriah Waterland if (ADM(instance, "newonly") || ADM(instance, "quit")) {
915c51f124SMoriah Waterland /*
925c51f124SMoriah Waterland * new instance is required, or quit if not new
935c51f124SMoriah Waterland */
945c51f124SMoriah Waterland
955c51f124SMoriah Waterland msgtext = MSG_NEWONLY;
965c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) {
975c51f124SMoriah Waterland ptext(stderr, msgtext, pkgabrv);
985c51f124SMoriah Waterland } else {
995c51f124SMoriah Waterland (void) fprintf(stdout, "install-new-only=true\n");
1005c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=4\n");
1015c51f124SMoriah Waterland }
1025c51f124SMoriah Waterland quit(4);
1035c51f124SMoriah Waterland }
1045c51f124SMoriah Waterland
1055c51f124SMoriah Waterland /*
1065c51f124SMoriah Waterland * package already installed and new instance not required
1075c51f124SMoriah Waterland * see if updating the same instance of the package
1085c51f124SMoriah Waterland */
1095c51f124SMoriah Waterland
1105c51f124SMoriah Waterland samearch = nsamearch = 0;
1115c51f124SMoriah Waterland sameinst = NULL;
1125c51f124SMoriah Waterland for (i = 0; i < npkgs; i++) {
1135c51f124SMoriah Waterland if (strcmp(info[i].arch, pkgarch) == NULL) {
1145c51f124SMoriah Waterland samearch = i;
1155c51f124SMoriah Waterland nsamearch++;
1165c51f124SMoriah Waterland if (strcmp(info[i].version, pkgvers) == NULL) {
1175c51f124SMoriah Waterland sameinst = info[i].pkginst;
1185c51f124SMoriah Waterland }
1195c51f124SMoriah Waterland }
1205c51f124SMoriah Waterland }
1215c51f124SMoriah Waterland
1225c51f124SMoriah Waterland if (sameinst) {
1235c51f124SMoriah Waterland /* same instance of package */
1245c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) {
1255c51f124SMoriah Waterland ptext(stderr, MSG_SAME);
1265c51f124SMoriah Waterland } else {
1275c51f124SMoriah Waterland (void) fprintf(stdout, "install-same-instance=true\n");
1285c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=0\n");
1295c51f124SMoriah Waterland }
1305c51f124SMoriah Waterland
131*9ab815e1SGarrett D'Amore inst = sameinst;
1325c51f124SMoriah Waterland same_pkg++;
1335c51f124SMoriah Waterland (*updatingExisting)++;
1345c51f124SMoriah Waterland return (inst);
1355c51f124SMoriah Waterland }
1365c51f124SMoriah Waterland
1375c51f124SMoriah Waterland if (ADM(instance, "overwrite")) {
1385c51f124SMoriah Waterland /* not the same instance of the package */
1395c51f124SMoriah Waterland if (npkgs == 1) {
1405c51f124SMoriah Waterland samearch = 0; /* use only package we know about */
1415c51f124SMoriah Waterland } else if (nsamearch != 1) {
1425c51f124SMoriah Waterland /*
1435c51f124SMoriah Waterland * more than one instance of the same ARCH is already
1445c51f124SMoriah Waterland * installed on this machine
1455c51f124SMoriah Waterland */
1465c51f124SMoriah Waterland msgtext = MSG_OVERWRITE;
1475c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) {
1485c51f124SMoriah Waterland ptext(stderr, msgtext);
1495c51f124SMoriah Waterland } else {
1505c51f124SMoriah Waterland (void) fprintf(stdout,
1515c51f124SMoriah Waterland "install-ovewrite=true\n");
1525c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=4\n");
1535c51f124SMoriah Waterland }
1545c51f124SMoriah Waterland quit(4);
1555c51f124SMoriah Waterland }
1565c51f124SMoriah Waterland
1575c51f124SMoriah Waterland inst = info[samearch].pkginst;
1585c51f124SMoriah Waterland
1595c51f124SMoriah Waterland (*updatingExisting)++;
1605c51f124SMoriah Waterland return (inst);
1615c51f124SMoriah Waterland }
1625c51f124SMoriah Waterland
1635c51f124SMoriah Waterland if (ADM(instance, "unique")) {
1645c51f124SMoriah Waterland if (maxinst <= npkgs) {
1655c51f124SMoriah Waterland /* too many instances */
1665c51f124SMoriah Waterland msgtext = MSG_UNIQ1;
1675c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) {
1685c51f124SMoriah Waterland ptext(stderr, msgtext, pkgabrv);
1695c51f124SMoriah Waterland } else {
1705c51f124SMoriah Waterland (void) fprintf(stdout,
1715c51f124SMoriah Waterland "install-too-many-instances=true\n");
1725c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=4\n");
1735c51f124SMoriah Waterland }
1745c51f124SMoriah Waterland quit(4);
1755c51f124SMoriah Waterland }
1765c51f124SMoriah Waterland inst = nextinst();
1775c51f124SMoriah Waterland return (inst);
1785c51f124SMoriah Waterland }
1795c51f124SMoriah Waterland
1805c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) {
1815c51f124SMoriah Waterland if (echoGetFlag() == B_FALSE) {
1825c51f124SMoriah Waterland msgtext = MSG_NOINTERACT;
1835c51f124SMoriah Waterland ptext(stderr, msgtext);
1845c51f124SMoriah Waterland quit(5);
1855c51f124SMoriah Waterland }
1865c51f124SMoriah Waterland } else {
1875c51f124SMoriah Waterland (void) fprintf(stdout, "install-new-instance=true\n");
1885c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=1\n");
1895c51f124SMoriah Waterland }
1905c51f124SMoriah Waterland
1915c51f124SMoriah Waterland inst = prompt(info, npkgs);
1925c51f124SMoriah Waterland if (strcmp(inst, "new") == NULL) {
1935c51f124SMoriah Waterland inst = nextinst();
1945c51f124SMoriah Waterland return (inst);
1955c51f124SMoriah Waterland }
1965c51f124SMoriah Waterland
1975c51f124SMoriah Waterland (*updatingExisting)++;
1985c51f124SMoriah Waterland
1995c51f124SMoriah Waterland return (inst);
2005c51f124SMoriah Waterland }
2015c51f124SMoriah Waterland
2025c51f124SMoriah Waterland /*
2035c51f124SMoriah Waterland * This informs the caller whether the package in question is the same
2045c51f124SMoriah Waterland * version and architecture as an installed package of the same name.
2055c51f124SMoriah Waterland */
2065c51f124SMoriah Waterland
2075c51f124SMoriah Waterland int
is_samepkg(void)2085c51f124SMoriah Waterland is_samepkg(void) {
2095c51f124SMoriah Waterland return (same_pkg);
2105c51f124SMoriah Waterland }
2115c51f124SMoriah Waterland
2125c51f124SMoriah Waterland static char *
nextinst(void)2135c51f124SMoriah Waterland nextinst(void)
2145c51f124SMoriah Waterland {
2155c51f124SMoriah Waterland struct pkginfo info;
2165c51f124SMoriah Waterland int n;
2175c51f124SMoriah Waterland
2185c51f124SMoriah Waterland n = 2; /* requirements say start at 2 */
2195c51f124SMoriah Waterland
2205c51f124SMoriah Waterland info.pkginst = NULL;
2215c51f124SMoriah Waterland (void) strcpy(newinst, pkgabrv);
2225c51f124SMoriah Waterland while (pkginfo(&info, newinst, NULL, NULL) == 0) {
2235c51f124SMoriah Waterland (void) snprintf(newinst, sizeof (newinst),
2245c51f124SMoriah Waterland "%s.%d", pkgabrv, n++);
2255c51f124SMoriah Waterland }
2265c51f124SMoriah Waterland return (newinst);
2275c51f124SMoriah Waterland }
2285c51f124SMoriah Waterland
2295c51f124SMoriah Waterland static char *
prompt(struct pkginfo * info,int npkgs)2305c51f124SMoriah Waterland prompt(struct pkginfo *info, int npkgs)
2315c51f124SMoriah Waterland {
2325c51f124SMoriah Waterland CKMENU *menup;
2335c51f124SMoriah Waterland char *inst;
2345c51f124SMoriah Waterland char ans[MAX_INPUT];
2355c51f124SMoriah Waterland char header[256];
2365c51f124SMoriah Waterland char temp[256];
2375c51f124SMoriah Waterland int i;
2385c51f124SMoriah Waterland int n;
2395c51f124SMoriah Waterland
2405c51f124SMoriah Waterland if (maxinst > npkgs) {
2415c51f124SMoriah Waterland /*
2425c51f124SMoriah Waterland * the user may choose to install a completely new
2435c51f124SMoriah Waterland * instance of this package
2445c51f124SMoriah Waterland */
2455c51f124SMoriah Waterland n = ckyorn(ans, NULL, NULL, MSG_GETINST_HELP1,
2465c51f124SMoriah Waterland MSG_GETINST_PROMPT1);
2475c51f124SMoriah Waterland if (n != 0) {
2485c51f124SMoriah Waterland quit(n);
2495c51f124SMoriah Waterland }
2505c51f124SMoriah Waterland if (strchr("yY", *ans) != NULL) {
2515c51f124SMoriah Waterland return ("new");
2525c51f124SMoriah Waterland }
2535c51f124SMoriah Waterland }
2545c51f124SMoriah Waterland
2555c51f124SMoriah Waterland (void) snprintf(header, sizeof (header), MSG_GETINST_HEADER, pkgabrv);
2565c51f124SMoriah Waterland menup = allocmenu(header, CKALPHA);
2575c51f124SMoriah Waterland
2585c51f124SMoriah Waterland for (i = 0; i < npkgs; i++) {
2595c51f124SMoriah Waterland (void) snprintf(temp, sizeof (temp),
2605c51f124SMoriah Waterland "%s %s\n(%s) %s", info[i].pkginst,
2615c51f124SMoriah Waterland info[i].name, info[i].arch, info[i].version);
2625c51f124SMoriah Waterland if (setitem(menup, temp)) {
2635c51f124SMoriah Waterland progerr("no memory");
2645c51f124SMoriah Waterland quit(99);
2655c51f124SMoriah Waterland }
2665c51f124SMoriah Waterland }
2675c51f124SMoriah Waterland
2685c51f124SMoriah Waterland if (npkgs == 1) {
2695c51f124SMoriah Waterland printmenu(menup);
2705c51f124SMoriah Waterland if (n = ckyorn(ans, NULL, NULL, NULL, MSG_GETINST_PROMPT0))
2715c51f124SMoriah Waterland quit(n);
2725c51f124SMoriah Waterland if (strchr("yY", *ans) == NULL)
2735c51f124SMoriah Waterland quit(3);
2745c51f124SMoriah Waterland (void) strcpy(newinst, info[0].pkginst);
2755c51f124SMoriah Waterland } else {
2765c51f124SMoriah Waterland if (n = ckitem(menup, &inst, 1, NULL, NULL, MSG_GETINST_HELP2,
2775c51f124SMoriah Waterland MSG_GETINST_PROMPT2))
2785c51f124SMoriah Waterland quit(n);
2795c51f124SMoriah Waterland (void) strcpy(newinst, inst);
2805c51f124SMoriah Waterland }
2815c51f124SMoriah Waterland (void) setitem(menup, 0); /* clear resource usage */
2825c51f124SMoriah Waterland free(menup); /* clear resource usage */
2835c51f124SMoriah Waterland
2845c51f124SMoriah Waterland return (newinst);
2855c51f124SMoriah Waterland }
286