1/* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28/* All Rights Reserved */ 29 30 31 32#include <stdio.h> 33#include <stdlib.h> 34#include <unistd.h> 35#include <string.h> 36#include <dirent.h> 37#include <ctype.h> 38#include <sys/utsname.h> 39#include <locale.h> 40#include <libintl.h> 41#include <pkglib.h> 42#include <libinst.h> 43#include <libadm.h> 44 45#ifdef MAILCMD 46#undef MAILCMD 47#define MAILCMD "/bin/mail" 48#endif /* MAILCMD */ 49#define ERR_MAIL "unable to send electronic mail notification" 50#define ERR_OVERWRITE "unable to determine overwrite list" 51#define ERR_PIPE "unable to open pipe to process <%s>" 52#define ASK_CONT "Do you want to continue processing this package" 53#define MSG_CONFLICT "The following files are currently being used by " \ 54 "other packages on the system, and may be " \ 55 "overwritten by the installation of this pre-SVR4 " \ 56 "package:" 57#define HLP_CONFLICT "If you choose to continue installation, it is " \ 58 "possible that you will overwrite files which are " \ 59 "part of another package that is already installed " \ 60 "on the system. If you want to assure that the " \ 61 "files are not overwritten, answer 'n' to stop the " \ 62 "installation process." 63#define MSG_NOTVER "The media being processed is in an old (pre-SVR4) " \ 64 "format and it is not possible to verify that the " \ 65 "inserted media belongs to the <%s> package." 66#define HLP_NOTVER "If you choose to continue installation, it is " \ 67 "possible that you will install the wrong package. " \ 68 "If you are sure the media being installed contains " \ 69 "the package you wish to install, answer 'y' to " \ 70 "continue the installation process." 71#define MSG_CONFIRM "The media being processed is in an old (pre-SVR4) " \ 72 "format and appears to be part of the <%s> package." 73#define HLP_CONFIRM "The installation of older-style (pre-SVR4) packages " \ 74 "is, in general, not as robust as installing " \ 75 "standard packages. Older packages may attempt " \ 76 "things during installation which overwrite existing " \ 77 "files or otherwise modify the system without your " \ 78 "approval. If you wish to allow installation of " \ 79 "identified pre-SVR4 package, answer 'y' to continue " \ 80 "the installation process." 81 82static char *Rlist[] = { 83 "/install/install/Rlist", 84 "/install/install/RLIST", 85 "/install/install/rlist", 86 NULL 87}; 88 89static char ckcmd[] = "/usr/sbin/pkgchk -L -i %s"; 90 91/* 92 * Remove the list & both #defines below for on1095 -- JST 93 * Further, please note : 94 * This is NOT a database (Oh, yeah it looks like it, but it isn't). For that 95 * reason these are in alphabetical order. Any additions must maintain this 96 * order and must not increase the list length beyond 120. 97 */ 98#define TREEHEIGHT 7 99#define TREEFILL 4 /* number of fill entries per side */ 100 101#ifdef ALLOW_EXCEPTION_PKG_LIST 102static char *x_pkg[] = 103{ 104 "AAAA1", /* fill to avoid constraint tests in loop */ 105 "AAAA2", 106 "AAAA3", 107 "AAAA4", 108 /* '+' means packages known to be non-compliant */ 109 "SPROcpl", /* + bugID 1133962 */ 110 "SPROlklnt", /* + SW Lock_Lint */ 111 "SPROltool", /* + SW Loop Profiling Tools */ 112 "SPROssbd", /* + SW ssbd component for SC 3.0 */ 113 "SPROtha", /* + Performance Analzyer */ 114 "SUNW3270c", /* + SunLink Client 3270 */ 115 "SUNW3270g", /* SunLink CG3270 8.0 */ 116 "SUNW3270t", /* + SunLink TN3270*Server */ 117 "SUNW86nma", /* SunNet Manager Core Tools for x86 */ 118 "SUNW86nmc", /* SunNet Manager Agents & Libraries for x86 */ 119 "SUNW86nmp", /* SunNet Manager SNMP daemon for x86 */ 120 "SUNWabcg", /* SunLink CG320 8.0 User's Guide */ 121 "SUNWbf", /* + 2.0 FDDI/S Beta */ 122 "SUNWbsccu", /* SunLink BSC Core Util */ 123 "SUNWbscdr", /* SunLink BSC Drivers */ 124 "SUNWcosiA", /* OSI Core Stack Kernel Files 1 */ 125 "SUNWcosiC", /* Stack Mgmnt Utilities 2 */ 126 "SUNWcosia", /* + OSI Core Stack Kernel Files */ 127 "SUNWcosib", /* OSI Core Stack Configuration Files */ 128 "SUNWcosic", /* OSI Core Stack Utilities */ 129 "SUNWcosid", /* OSI Core Stack Development Kit (new pakage) */ 130 "SUNWcosij", /* OSI Core Stack User Space Utilities */ 131 "SUNWdniCU", /* + SunLink DNI Core Utilities 8.0 */ 132 "SUNWdniKR", /* + SunLink DNI Kernel 8.0 */ 133 "SUNWdniMA", /* SunLink DNI Mail Agent 8.0 */ 134 "SUNWflex", /* + FLEX LM DEVEL PKG */ 135 "SUNWftama", /* OSI FTAM Configuration Files */ 136 "SUNWftamb", /* OSI FTAM Executable, Libraries and Man Pages */ 137 "SUNWhsis", /* SunConnect HSI/S */ 138 "SUNWjaCL", /* + Frances Ho confirms for SUNpics */ 139 "SUNWjncmt", /* SunNet Manager Core Tools(Japan) */ 140 "SUNWjnmag", /* SunNet Manager Agents & Libraries (Japan) */ 141 "SUNWjnmpd", /* SunNet Manager SNMP daemon(Japan) */ 142 "SUNWlicsw", /* + FLEXlm */ 143 "SUNWlit", /* STE LIC INSTALL TOOL */ 144 "SUNWllc2a", /* X.25 LLC2 KRNL MOD, INCLDS FL */ 145 "SUNWllc2b", /* X.25 USR PROG, MAN PAGES */ 146 "SUNWmd", /* + Suhas Patil request 1994-07-12 */ 147 "SUNWmhs1a", /* MHS Message Transfer Agent Configuration Files */ 148 "SUNWmhs1b", /* MHS Message Transfer Agent Executable and Man Pgs */ 149 "SUNWomgta", /* OSI Mgmnt Configuration Files */ 150 "SUNWomgtb", /* OSI Mgmnt Configuration Files */ 151 "SUNWomgtc", /* OSI Mgmnt SunNet Mgr Proxy Agent Executable Files */ 152 "SUNWomgtd", /* OSI Mgmnt SunNet Mgr Proxy Agent Config Files */ 153 "SUNWp2pnm", /* SunLink SNA Peer-to-Peer Network Management */ 154 "SUNWprsto", /* + Varun Mehta request 1994-07-11 */ 155 "SUNWrup2p", /* Sunlink SNA Peer-to-Peer Run Time Environment */ 156 "SUNWs3270", /* + SunLink SNA3270/RJE */ 157 "SUNWscmmd", /* SunLink Comm Daemon */ 158 "SUNWsdlc", /* SunLink IBM SDLC */ 159 "SUNWsm-ml", /* ShowMe Motif Libs */ 160 "SUNWsm-ol", /* ShowMe Online help */ 161 "SUNWsmCmg", 162 "SUNWsmap", /* SunLink Mapper */ 163 "SUNWsmaud", /* ShowMe Audio */ 164 "SUNWsmsha", /* ShowMe SharedApp */ 165 "SUNWsmvid", /* ShowMe Video */ 166 "SUNWsmwtb", /* ShowMe Whiteboard */ 167 "SUNWsnmag", /* + Steve Wong request 1994-02-15 */ 168 "SUNWsnmct", /* + Steve Wong request 1994-02-15 */ 169 "SUNWsnmja", /* SunNet Manager 2.2 Japanese feature */ 170 "SUNWsnmpd", /* SunNet Manager SNMP daemon */ 171 "SUNWsnp2p", /* + SunLink SNA P-to-P */ 172 "SUNWspii", /* 1.0 SPARCprinterII */ 173 "SUNWsrjec", /* + SunLink Client SNA RJE */ 174 "SUNWsteCL", /* + Frances Ho confirms for SUNPics */ 175 "SUNWsteNP", /* 2.5 NeWSprint */ 176 "SUNWte320", /* + TE320 8.0 */ 177 "SUNWtris", /* SunConnect TRI/S */ 178 "SUNWvtcfg", /* OSI Virtual Terminal Configuration Files */ 179 "SUNWvtexe", /* OSI Virtual Terminal User Program and Man Pages */ 180 "SUNWx25a", /* + X.25 KRNL MOD, INCLDS FLS */ 181 "SUNWx25b", /* + X.25 USR PROG AND LIB */ 182 "zzzz1", /* fill to avoid constraint tests in loop */ 183 "zzzz2", 184 "zzzz3", 185 "zzzz4" 186}; 187#endif 188 189/* 190 * Structure to hold the list of pkg names that are known to not behave 191 * properly when sym link destinations are not followed. 192 */ 193 194#ifdef ALLOW_EXCEPTION_PKG_LIST 195static char *x_pkg_link[] = 196{ 197 "AAAA1", /* fill to avoid constraint tests in loop */ 198 "AAAA2", 199 "AAAA3", 200 "AAAA4", 201 /* '+' means packages known to be non-compliant */ 202 "SUNWixfta", 203 "SUNWixsna", 204 "zzzz1", /* fill to avoid constraint tests in loop */ 205 "zzzz2", 206 "zzzz3", 207 "zzzz4" 208}; 209#endif 210 211/* 212 * This function determines if the package being added is a known old-style 213 * package which requires user interaction during procedure scripts. It is 214 * to be removed for on1095. -- JST 215 * It also is used for the determining if a pkg is known to have symlinks 216 * that need to be processed the old way. 217 */ 218 219#ifdef ALLOW_EXCEPTION_PKG_LIST 220int 221exception_pkg(char *pkginst, int pkg_list) 222{ 223 int retvalue = 0; 224 int list_sz; 225 int list_cntr; /* starting point for binary search */ 226 register int pos; /* current position */ 227 register int level; /* current height in the tree */ 228 register int incr; /* increment for step */ 229 int result; /* result of strcmp */ 230 register char **x_ptr = x_pkg; 231 register char **x_ptr_link = x_pkg_link; 232 char *pkgend; 233 char *pkgname = strdup(pkginst); 234 235 /* 236 * NOTE : If more structures need to be defined the following if 237 * statement needs to be revised to handle multiple flags 238 */ 239 240 if (pkg_list) 241 list_sz = (sizeof (x_pkg_link) / sizeof (char *)); 242 else 243 list_sz = (sizeof (x_pkg) / sizeof (char *)); 244 245 /* 246 * NOTE : shifts are used instead of integer division to save 247 * time. Numerous other checks are omitted also. This tree 248 * contains double nodes but is entirely connected and closed. 249 */ 250 251 list_cntr = list_sz >> 1; 252 incr = list_cntr - TREEFILL; 253 254 pkgend = strchr(pkgname, '.'); 255 256 if (pkgend) 257 *pkgend = '\0'; /* terminate the instance to a name */ 258 259 for (level = TREEHEIGHT, /* start at the top level */ 260 pos = list_cntr; /* ... in the middle */ 261 level; /* for as long as we're in the tree */ 262 level--, pos += (result > 0) ? incr : -incr) { 263 264 if (pkg_list) 265 result = strcmp(pkgname, *(x_ptr_link + pos)); 266 else 267 result = strcmp(pkgname, *(x_ptr + pos)); 268 269 if (result == 0) { 270 retvalue = 1; 271 break; 272 } 273 274 incr = (incr & 0x0001) | (incr >> 1); /* halve it & rnd up */ 275 } 276 277 free(pkgname); 278 279 return (retvalue); 280} 281 282#endif 283 284void 285psvr4pkg(char **ppkg) 286{ 287 struct dirent *drp; 288 DIR *dirfp; 289 char *pt; 290 int n; 291 char ans[MAX_INPUT], path[PATH_MAX]; 292 293 if (*ppkg) { 294 (void) snprintf(path, sizeof (path), 295 "/install/new/usr/options/%s.name", 296 *ppkg); 297 if (access(path, 0)) { 298 ptext(stderr, gettext(MSG_NOTVER), *ppkg); 299 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_NOTVER), 300 gettext(ASK_CONT))) 301 quit(n); 302 if (strchr("yY", *ans) == NULL) 303 quit(3); 304 } 305 return; 306 } 307 308 if (dirfp = opendir("/install/new/usr/options")) { 309 while (drp = readdir(dirfp)) { 310 if (drp->d_name[0] == '.') 311 continue; 312 if (pt = strchr(drp->d_name, '.')) { 313 if (strcmp(pt, ".name") == 0) { 314 *pt = '\0'; 315 *ppkg = qstrdup(drp->d_name); 316 break; 317 } 318 } 319 } 320 (void) closedir(dirfp); 321 } 322 323 if (*ppkg) { 324 ptext(stderr, gettext(MSG_CONFIRM), *ppkg); 325 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_CONFIRM), 326 gettext(ASK_CONT))) 327 quit(n); 328 } else { 329 ptext(stderr, gettext(MSG_NOTVER), *ppkg); 330 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_NOTVER), 331 gettext(ASK_CONT))) 332 quit(n); 333 } 334 if (strchr("yY", *ans) == NULL) 335 quit(3); 336} 337 338void 339psvr4cnflct(void) 340{ 341 FILE *pp; 342 int n, found; 343 char *pt, 344 ans[MAX_INPUT], 345 cmd[PATH_MAX+sizeof (ckcmd)], 346 path[PATH_MAX]; 347 348 for (n = 0; Rlist[n] != NULL; n++) { 349 if (access(Rlist[n], 0) == 0) 350 break; 351 } 352 if (Rlist[n] == NULL) 353 return; /* Rlist file not found on device */ 354 355 (void) sprintf(cmd, ckcmd, Rlist[n]); 356 echo(gettext("## Checking for conflicts with installed packages")); 357 echo(gettext(" (using %s provided by pre-SVR4 package)"), Rlist[n]); 358 if ((pp = popen(cmd, "r")) == NULL) { 359 progerr(gettext(ERR_PIPE), cmd); 360 progerr(gettext(ERR_OVERWRITE)); 361 quit(99); 362 } 363 364 found = 0; 365 while (fgets(path, PATH_MAX, pp)) { 366 if (!found++) 367 ptext(stderr, gettext(MSG_CONFLICT)); 368 if (pt = strpbrk(path, " \t\n")) 369 *pt = '\0'; 370 echo("\t%s", path); 371 } 372 if (pclose(pp)) { 373 progerr(gettext(ERR_OVERWRITE)); 374 quit(99); 375 } 376 377 if (found) { 378 if (n = ckyorn(ans, NULL, NULL, gettext(HLP_CONFLICT), 379 gettext(ASK_CONT))) 380 quit(n); 381 if (strchr("yY", *ans) == NULL) 382 quit(3); 383 } 384} 385 386void 387psvr4mail(char *list, char *msg, int retcode, char *pkg) 388{ 389 struct utsname utsbuf; 390 FILE *pp; 391 char cmd[BUFSIZ]; 392 393 if (list == NULL) 394 return; 395 396 while (isspace(*list)) 397 list++; 398 if (*list == '\0') 399 return; 400 401 /* send e-mail notifications */ 402 (void) snprintf(cmd, sizeof (cmd), "%s %s", MAILCMD, list); 403 if ((pp = popen(cmd, "w")) == NULL) { 404 progerr(gettext(ERR_PIPE), MAILCMD); 405 progerr(gettext(ERR_MAIL)); 406 quit(99); 407 } 408 409 (void) strcpy(utsbuf.nodename, gettext("(unknown)")); 410 (void) uname(&utsbuf); 411 ptext(pp, msg, pkg, utsbuf.nodename, retcode); 412 413 if (pclose(pp)) { 414 progerr(gettext(ERR_MAIL)); 415 quit(99); 416 } 417} 418