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;
489ab815e1SGarrett 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++) {
113*c57b7750SToomas Soome 		if (strcmp(info[i].arch, pkgarch) == 0) {
1145c51f124SMoriah Waterland 			samearch = i;
1155c51f124SMoriah Waterland 			nsamearch++;
116*c57b7750SToomas Soome 			if (strcmp(info[i].version, pkgvers) == 0) {
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 
1319ab815e1SGarrett 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);
192*c57b7750SToomas Soome 	if (strcmp(inst, "new") == 0) {
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