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
82 static char *Rlist[] = {
83 "/install/install/Rlist",
84 "/install/install/RLIST",
85 "/install/install/rlist",
86 NULL
87 };
88
89 static 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
102 static 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
195 static 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
220 int
exception_pkg(char * pkginst,int pkg_list)221 exception_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
284 void
psvr4pkg(char ** ppkg)285 psvr4pkg(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
338 void
psvr4cnflct(void)339 psvr4cnflct(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
386 void
psvr4mail(char * list,char * msg,int retcode,char * pkg)387 psvr4mail(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