1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*5c51f124SMoriah Waterland /* All Rights Reserved */ 29*5c51f124SMoriah Waterland 30*5c51f124SMoriah Waterland 31*5c51f124SMoriah Waterland #include <stdio.h> 32*5c51f124SMoriah Waterland #include <string.h> 33*5c51f124SMoriah Waterland #include <stdlib.h> 34*5c51f124SMoriah Waterland #include <unistd.h> 35*5c51f124SMoriah Waterland #include <valtools.h> 36*5c51f124SMoriah Waterland #include <locale.h> 37*5c51f124SMoriah Waterland #include <libintl.h> 38*5c51f124SMoriah Waterland #include <pkginfo.h> 39*5c51f124SMoriah Waterland #include "install.h" 40*5c51f124SMoriah Waterland #include <pkglib.h> 41*5c51f124SMoriah Waterland #include "libadm.h" 42*5c51f124SMoriah Waterland #include "libinst.h" 43*5c51f124SMoriah Waterland #include "pkginstall.h" 44*5c51f124SMoriah Waterland #include "messages.h" 45*5c51f124SMoriah Waterland 46*5c51f124SMoriah Waterland extern struct admin adm; 47*5c51f124SMoriah Waterland extern char *pkgarch, *pkgvers, *msgtext, *pkgabrv; 48*5c51f124SMoriah Waterland extern int opresvr4, maxinst; 49*5c51f124SMoriah Waterland 50*5c51f124SMoriah Waterland static char newinst[PKGSIZ]; 51*5c51f124SMoriah Waterland static char *nextinst(void); 52*5c51f124SMoriah Waterland static char *prompt(struct pkginfo *info, int npkgs); 53*5c51f124SMoriah Waterland static int same_pkg; /* same PKG, ARCH and VERSION */ 54*5c51f124SMoriah Waterland 55*5c51f124SMoriah Waterland /* 56*5c51f124SMoriah Waterland * This returns the correct package instance based on how many packages are 57*5c51f124SMoriah Waterland * already installed. If there are none (npkgs == 0), it just returns the 58*5c51f124SMoriah Waterland * package abbreviation. Otherwise, it interacts with the user (or reads the 59*5c51f124SMoriah Waterland * admin file) to determine if we should overwrite an instance which is 60*5c51f124SMoriah Waterland * already installed, or possibly install a new instance of this package 61*5c51f124SMoriah Waterland */ 62*5c51f124SMoriah Waterland char * 63*5c51f124SMoriah Waterland getinst(int *updatingExisting, struct pkginfo *info, int npkgs, 64*5c51f124SMoriah Waterland boolean_t a_preinstallCheck) 65*5c51f124SMoriah Waterland { 66*5c51f124SMoriah Waterland char *inst; 67*5c51f124SMoriah Waterland char *sameinst; 68*5c51f124SMoriah Waterland int i; 69*5c51f124SMoriah Waterland int nsamearch; 70*5c51f124SMoriah Waterland int samearch; 71*5c51f124SMoriah Waterland 72*5c51f124SMoriah Waterland /* entry debugging info */ 73*5c51f124SMoriah Waterland 74*5c51f124SMoriah Waterland same_pkg = 0; 75*5c51f124SMoriah Waterland 76*5c51f124SMoriah Waterland /* 77*5c51f124SMoriah Waterland * If this is the first instance of the package, it's called the by 78*5c51f124SMoriah Waterland * the package abbreviation. 79*5c51f124SMoriah Waterland */ 80*5c51f124SMoriah Waterland 81*5c51f124SMoriah Waterland if (npkgs == 0) { 82*5c51f124SMoriah Waterland return (pkgabrv); 83*5c51f124SMoriah Waterland } 84*5c51f124SMoriah Waterland 85*5c51f124SMoriah Waterland /* 86*5c51f124SMoriah Waterland * this package is already installed; determine how to handle the 87*5c51f124SMoriah Waterland * new instance of the package to install 88*5c51f124SMoriah Waterland */ 89*5c51f124SMoriah Waterland 90*5c51f124SMoriah Waterland if (ADM(instance, "newonly") || ADM(instance, "quit")) { 91*5c51f124SMoriah Waterland /* 92*5c51f124SMoriah Waterland * new instance is required, or quit if not new 93*5c51f124SMoriah Waterland */ 94*5c51f124SMoriah Waterland 95*5c51f124SMoriah Waterland msgtext = MSG_NEWONLY; 96*5c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) { 97*5c51f124SMoriah Waterland ptext(stderr, msgtext, pkgabrv); 98*5c51f124SMoriah Waterland } else { 99*5c51f124SMoriah Waterland (void) fprintf(stdout, "install-new-only=true\n"); 100*5c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=4\n"); 101*5c51f124SMoriah Waterland } 102*5c51f124SMoriah Waterland quit(4); 103*5c51f124SMoriah Waterland } 104*5c51f124SMoriah Waterland 105*5c51f124SMoriah Waterland /* 106*5c51f124SMoriah Waterland * package already installed and new instance not required 107*5c51f124SMoriah Waterland * see if updating the same instance of the package 108*5c51f124SMoriah Waterland */ 109*5c51f124SMoriah Waterland 110*5c51f124SMoriah Waterland samearch = nsamearch = 0; 111*5c51f124SMoriah Waterland sameinst = NULL; 112*5c51f124SMoriah Waterland for (i = 0; i < npkgs; i++) { 113*5c51f124SMoriah Waterland if (strcmp(info[i].arch, pkgarch) == NULL) { 114*5c51f124SMoriah Waterland samearch = i; 115*5c51f124SMoriah Waterland nsamearch++; 116*5c51f124SMoriah Waterland if (strcmp(info[i].version, pkgvers) == NULL) { 117*5c51f124SMoriah Waterland sameinst = info[i].pkginst; 118*5c51f124SMoriah Waterland } 119*5c51f124SMoriah Waterland } 120*5c51f124SMoriah Waterland } 121*5c51f124SMoriah Waterland 122*5c51f124SMoriah Waterland if (sameinst) { 123*5c51f124SMoriah Waterland /* same instance of package */ 124*5c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) { 125*5c51f124SMoriah Waterland ptext(stderr, MSG_SAME); 126*5c51f124SMoriah Waterland } else { 127*5c51f124SMoriah Waterland (void) fprintf(stdout, "install-same-instance=true\n"); 128*5c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=0\n"); 129*5c51f124SMoriah Waterland } 130*5c51f124SMoriah Waterland 131*5c51f124SMoriah Waterland inst = sameinst; /* can't be overwriting a pre-svr4 package */ 132*5c51f124SMoriah Waterland same_pkg++; 133*5c51f124SMoriah Waterland (*updatingExisting)++; 134*5c51f124SMoriah Waterland return (inst); 135*5c51f124SMoriah Waterland } 136*5c51f124SMoriah Waterland 137*5c51f124SMoriah Waterland if (ADM(instance, "overwrite")) { 138*5c51f124SMoriah Waterland /* not the same instance of the package */ 139*5c51f124SMoriah Waterland if (npkgs == 1) { 140*5c51f124SMoriah Waterland samearch = 0; /* use only package we know about */ 141*5c51f124SMoriah Waterland } else if (nsamearch != 1) { 142*5c51f124SMoriah Waterland /* 143*5c51f124SMoriah Waterland * more than one instance of the same ARCH is already 144*5c51f124SMoriah Waterland * installed on this machine 145*5c51f124SMoriah Waterland */ 146*5c51f124SMoriah Waterland msgtext = MSG_OVERWRITE; 147*5c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) { 148*5c51f124SMoriah Waterland ptext(stderr, msgtext); 149*5c51f124SMoriah Waterland } else { 150*5c51f124SMoriah Waterland (void) fprintf(stdout, 151*5c51f124SMoriah Waterland "install-ovewrite=true\n"); 152*5c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=4\n"); 153*5c51f124SMoriah Waterland } 154*5c51f124SMoriah Waterland quit(4); 155*5c51f124SMoriah Waterland } 156*5c51f124SMoriah Waterland 157*5c51f124SMoriah Waterland inst = info[samearch].pkginst; 158*5c51f124SMoriah Waterland if (info[samearch].status == PI_PRESVR4) { 159*5c51f124SMoriah Waterland opresvr4++; /* overwriting a pre-svr4 package */ 160*5c51f124SMoriah Waterland } 161*5c51f124SMoriah Waterland 162*5c51f124SMoriah Waterland (*updatingExisting)++; 163*5c51f124SMoriah Waterland return (inst); 164*5c51f124SMoriah Waterland } 165*5c51f124SMoriah Waterland 166*5c51f124SMoriah Waterland if (ADM(instance, "unique")) { 167*5c51f124SMoriah Waterland if (maxinst <= npkgs) { 168*5c51f124SMoriah Waterland /* too many instances */ 169*5c51f124SMoriah Waterland msgtext = MSG_UNIQ1; 170*5c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) { 171*5c51f124SMoriah Waterland ptext(stderr, msgtext, pkgabrv); 172*5c51f124SMoriah Waterland } else { 173*5c51f124SMoriah Waterland (void) fprintf(stdout, 174*5c51f124SMoriah Waterland "install-too-many-instances=true\n"); 175*5c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=4\n"); 176*5c51f124SMoriah Waterland } 177*5c51f124SMoriah Waterland quit(4); 178*5c51f124SMoriah Waterland } 179*5c51f124SMoriah Waterland inst = nextinst(); 180*5c51f124SMoriah Waterland return (inst); 181*5c51f124SMoriah Waterland } 182*5c51f124SMoriah Waterland 183*5c51f124SMoriah Waterland if (a_preinstallCheck == B_FALSE) { 184*5c51f124SMoriah Waterland if (echoGetFlag() == B_FALSE) { 185*5c51f124SMoriah Waterland msgtext = MSG_NOINTERACT; 186*5c51f124SMoriah Waterland ptext(stderr, msgtext); 187*5c51f124SMoriah Waterland quit(5); 188*5c51f124SMoriah Waterland } 189*5c51f124SMoriah Waterland } else { 190*5c51f124SMoriah Waterland (void) fprintf(stdout, "install-new-instance=true\n"); 191*5c51f124SMoriah Waterland (void) fprintf(stdout, "ckinstance=1\n"); 192*5c51f124SMoriah Waterland } 193*5c51f124SMoriah Waterland 194*5c51f124SMoriah Waterland inst = prompt(info, npkgs); 195*5c51f124SMoriah Waterland if (strcmp(inst, "new") == NULL) { 196*5c51f124SMoriah Waterland inst = nextinst(); 197*5c51f124SMoriah Waterland return (inst); 198*5c51f124SMoriah Waterland } 199*5c51f124SMoriah Waterland 200*5c51f124SMoriah Waterland (*updatingExisting)++; 201*5c51f124SMoriah Waterland 202*5c51f124SMoriah Waterland /* see if this instance is presvr4 */ 203*5c51f124SMoriah Waterland for (i = 0; i < npkgs; i++) { 204*5c51f124SMoriah Waterland if (strcmp(inst, info[i].pkginst) == NULL) { 205*5c51f124SMoriah Waterland if (info[i].status == PI_PRESVR4) { 206*5c51f124SMoriah Waterland opresvr4++; 207*5c51f124SMoriah Waterland } 208*5c51f124SMoriah Waterland break; 209*5c51f124SMoriah Waterland } 210*5c51f124SMoriah Waterland } 211*5c51f124SMoriah Waterland 212*5c51f124SMoriah Waterland return (inst); 213*5c51f124SMoriah Waterland } 214*5c51f124SMoriah Waterland 215*5c51f124SMoriah Waterland /* 216*5c51f124SMoriah Waterland * This informs the caller whether the package in question is the same 217*5c51f124SMoriah Waterland * version and architecture as an installed package of the same name. 218*5c51f124SMoriah Waterland */ 219*5c51f124SMoriah Waterland 220*5c51f124SMoriah Waterland int 221*5c51f124SMoriah Waterland is_samepkg(void) { 222*5c51f124SMoriah Waterland return (same_pkg); 223*5c51f124SMoriah Waterland } 224*5c51f124SMoriah Waterland 225*5c51f124SMoriah Waterland static char * 226*5c51f124SMoriah Waterland nextinst(void) 227*5c51f124SMoriah Waterland { 228*5c51f124SMoriah Waterland struct pkginfo info; 229*5c51f124SMoriah Waterland int n; 230*5c51f124SMoriah Waterland 231*5c51f124SMoriah Waterland n = 2; /* requirements say start at 2 */ 232*5c51f124SMoriah Waterland 233*5c51f124SMoriah Waterland info.pkginst = NULL; 234*5c51f124SMoriah Waterland (void) strcpy(newinst, pkgabrv); 235*5c51f124SMoriah Waterland while (pkginfo(&info, newinst, NULL, NULL) == 0) { 236*5c51f124SMoriah Waterland (void) snprintf(newinst, sizeof (newinst), 237*5c51f124SMoriah Waterland "%s.%d", pkgabrv, n++); 238*5c51f124SMoriah Waterland } 239*5c51f124SMoriah Waterland return (newinst); 240*5c51f124SMoriah Waterland } 241*5c51f124SMoriah Waterland 242*5c51f124SMoriah Waterland static char * 243*5c51f124SMoriah Waterland prompt(struct pkginfo *info, int npkgs) 244*5c51f124SMoriah Waterland { 245*5c51f124SMoriah Waterland CKMENU *menup; 246*5c51f124SMoriah Waterland char *inst; 247*5c51f124SMoriah Waterland char ans[MAX_INPUT]; 248*5c51f124SMoriah Waterland char header[256]; 249*5c51f124SMoriah Waterland char temp[256]; 250*5c51f124SMoriah Waterland int i; 251*5c51f124SMoriah Waterland int n; 252*5c51f124SMoriah Waterland 253*5c51f124SMoriah Waterland if (maxinst > npkgs) { 254*5c51f124SMoriah Waterland /* 255*5c51f124SMoriah Waterland * the user may choose to install a completely new 256*5c51f124SMoriah Waterland * instance of this package 257*5c51f124SMoriah Waterland */ 258*5c51f124SMoriah Waterland n = ckyorn(ans, NULL, NULL, MSG_GETINST_HELP1, 259*5c51f124SMoriah Waterland MSG_GETINST_PROMPT1); 260*5c51f124SMoriah Waterland if (n != 0) { 261*5c51f124SMoriah Waterland quit(n); 262*5c51f124SMoriah Waterland } 263*5c51f124SMoriah Waterland if (strchr("yY", *ans) != NULL) { 264*5c51f124SMoriah Waterland return ("new"); 265*5c51f124SMoriah Waterland } 266*5c51f124SMoriah Waterland } 267*5c51f124SMoriah Waterland 268*5c51f124SMoriah Waterland (void) snprintf(header, sizeof (header), MSG_GETINST_HEADER, pkgabrv); 269*5c51f124SMoriah Waterland menup = allocmenu(header, CKALPHA); 270*5c51f124SMoriah Waterland 271*5c51f124SMoriah Waterland for (i = 0; i < npkgs; i++) { 272*5c51f124SMoriah Waterland (void) snprintf(temp, sizeof (temp), 273*5c51f124SMoriah Waterland "%s %s\n(%s) %s", info[i].pkginst, 274*5c51f124SMoriah Waterland info[i].name, info[i].arch, info[i].version); 275*5c51f124SMoriah Waterland if (setitem(menup, temp)) { 276*5c51f124SMoriah Waterland progerr("no memory"); 277*5c51f124SMoriah Waterland quit(99); 278*5c51f124SMoriah Waterland } 279*5c51f124SMoriah Waterland } 280*5c51f124SMoriah Waterland 281*5c51f124SMoriah Waterland if (npkgs == 1) { 282*5c51f124SMoriah Waterland printmenu(menup); 283*5c51f124SMoriah Waterland if (n = ckyorn(ans, NULL, NULL, NULL, MSG_GETINST_PROMPT0)) 284*5c51f124SMoriah Waterland quit(n); 285*5c51f124SMoriah Waterland if (strchr("yY", *ans) == NULL) 286*5c51f124SMoriah Waterland quit(3); 287*5c51f124SMoriah Waterland (void) strcpy(newinst, info[0].pkginst); 288*5c51f124SMoriah Waterland } else { 289*5c51f124SMoriah Waterland if (n = ckitem(menup, &inst, 1, NULL, NULL, MSG_GETINST_HELP2, 290*5c51f124SMoriah Waterland MSG_GETINST_PROMPT2)) 291*5c51f124SMoriah Waterland quit(n); 292*5c51f124SMoriah Waterland (void) strcpy(newinst, inst); 293*5c51f124SMoriah Waterland } 294*5c51f124SMoriah Waterland (void) setitem(menup, 0); /* clear resource usage */ 295*5c51f124SMoriah Waterland free(menup); /* clear resource usage */ 296*5c51f124SMoriah Waterland 297*5c51f124SMoriah Waterland return (newinst); 298*5c51f124SMoriah Waterland } 299