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 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 
28 /*
29  * System includes
30  */
31 
32 #include <stdio.h>
33 #include <time.h>
34 #include <wait.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <ulimit.h>
38 #include <sys/stat.h>
39 #include <sys/statvfs.h>
40 #include <assert.h>
41 #include <fcntl.h>
42 #include <errno.h>
43 #include <ctype.h>
44 #include <dirent.h>
45 #include <string.h>
46 #include <signal.h>
47 #include <locale.h>
48 #include <libintl.h>
49 #include <pkgstrct.h>
50 #include <pkginfo.h>
51 #include <pkgdev.h>
52 #include <pkglocs.h>
53 #include <pwd.h>
54 
55 
56 /*
57  * consolidation pkg command library includes
58  */
59 
60 #include <pkglib.h>
61 
62 /*
63  * local pkg command library includes
64  */
65 
66 #include "libinst.h"
67 #include "libadm.h"
68 #include "messages.h"
69 
70 /*
71  * Name:	unpack_package_from_stream
72  * Description:	unpack a package from a stream into a temporary directory
73  * Arguments:	a_idsName - pointer to string representing the input data
74  *			stream containing the package to unpack
75  *		a_pkginst - pointer to string representing the name of
76  *			the package to unpack from the specified stream
77  *		a_tempDir - pointer to string representing the path to a
78  *			directory into which the package will be unpacked
79  * Returns:	boolean_t
80  *			== B_TRUE - package successfully unpacked from stream
81  *			== B_FALSE - failed to unpack package from stream
82  */
83 
84 boolean_t
unpack_package_from_stream(char * a_idsName,char * a_pkginst,char * a_tempDir)85 unpack_package_from_stream(char *a_idsName, char *a_pkginst, char *a_tempDir)
86 {
87 	int		dparts;
88 	char		instdir[PATH_MAX];
89 
90 	/* entry assertions */
91 
92 	assert(a_idsName != (char *)NULL);
93 	assert(a_pkginst != (char *)NULL);
94 	assert(a_tempDir != (char *)NULL);
95 
96 	/* entry debug information */
97 
98 	echoDebug(DBG_UNPACKSTRM_ENTRY);
99 	echoDebug(DBG_UNPACKSTRM_ARGS, a_pkginst, a_idsName, a_tempDir);
100 
101 	/* find the specified package in the datastream */
102 
103 	dparts = ds_findpkg(a_idsName, a_pkginst);
104 	if (dparts < 1) {
105 		progerr(gettext(ERR_DSARCH), a_pkginst);
106 		return (B_FALSE);
107 		/*NOTREACHED*/
108 	}
109 
110 	/*
111 	 * read in next part from stream, even if we decide
112 	 * later that we don't need it
113 	 */
114 
115 	/* create directory to hold this package instance */
116 
117 	if (snprintf(instdir, sizeof (instdir), "%s/%s", a_tempDir, a_pkginst)
118 	    >= PATH_MAX) {
119 		progerr(ERR_CREATE_PATH_2, a_tempDir, a_pkginst);
120 		return (B_FALSE);
121 	}
122 
123 	switch (fmkdir(instdir, 0755)) {
124 	case 0:	/* directory created */
125 		break;
126 	case 1: /* could not remove existing non-directory node */
127 		progerr(ERR_REMOVE, instdir, strerror(errno));
128 		return (B_FALSE);
129 	case 2: /* could not create specified new directory */
130 	default:
131 		progerr(ERR_UNPACK_FMKDIR, instdir, strerror(errno));
132 		return (B_FALSE);
133 	}
134 
135 	/* unpack package instance from stream to dir created */
136 
137 	echoDebug(DBG_UNPACKSTRM_UNPACKING, a_pkginst, a_idsName, instdir);
138 
139 	if (chdir(instdir)) {
140 		progerr(ERR_CHDIR, instdir);
141 		return (B_FALSE);
142 	}
143 
144 	while (dparts--) {
145 		if (ds_next(a_idsName, instdir)) {
146 			progerr(ERR_UNPACK_DSREAD, dparts+1, a_idsName, instdir,
147 				a_pkginst);
148 			return (B_FALSE);
149 		}
150 	}
151 
152 	if (chdir(get_PKGADM())) {
153 		progerr(gettext(ERR_CHDIR), get_PKGADM());
154 		return (B_FALSE);
155 	}
156 
157 	return (B_TRUE);
158 }
159