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
84boolean_t
85unpack_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