1*9781SMoriah.Waterland@Sun.COM /*
2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START
3*9781SMoriah.Waterland@Sun.COM *
4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the
5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License").
6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License.
7*9781SMoriah.Waterland@Sun.COM *
8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions
11*9781SMoriah.Waterland@Sun.COM * and limitations under the License.
12*9781SMoriah.Waterland@Sun.COM *
13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*9781SMoriah.Waterland@Sun.COM *
19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END
20*9781SMoriah.Waterland@Sun.COM */
21*9781SMoriah.Waterland@Sun.COM
22*9781SMoriah.Waterland@Sun.COM /*
23*9781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms.
25*9781SMoriah.Waterland@Sun.COM */
26*9781SMoriah.Waterland@Sun.COM
27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
29*9781SMoriah.Waterland@Sun.COM
30*9781SMoriah.Waterland@Sun.COM
31*9781SMoriah.Waterland@Sun.COM
32*9781SMoriah.Waterland@Sun.COM #include <stdio.h>
33*9781SMoriah.Waterland@Sun.COM #include <errno.h>
34*9781SMoriah.Waterland@Sun.COM #include <stdarg.h>
35*9781SMoriah.Waterland@Sun.COM #include <limits.h>
36*9781SMoriah.Waterland@Sun.COM #include <stdlib.h>
37*9781SMoriah.Waterland@Sun.COM #include <unistd.h>
38*9781SMoriah.Waterland@Sun.COM #include <fcntl.h>
39*9781SMoriah.Waterland@Sun.COM #include <ctype.h>
40*9781SMoriah.Waterland@Sun.COM #include <string.h>
41*9781SMoriah.Waterland@Sun.COM #include <sys/types.h>
42*9781SMoriah.Waterland@Sun.COM #include <sys/param.h>
43*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
44*9781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h>
45*9781SMoriah.Waterland@Sun.COM #include <sys/sysmacros.h>
46*9781SMoriah.Waterland@Sun.COM #include <dirent.h>
47*9781SMoriah.Waterland@Sun.COM #include <signal.h>
48*9781SMoriah.Waterland@Sun.COM #include <devmgmt.h>
49*9781SMoriah.Waterland@Sun.COM #include <openssl/pkcs12.h>
50*9781SMoriah.Waterland@Sun.COM #include <openssl/x509.h>
51*9781SMoriah.Waterland@Sun.COM #include <openssl/pkcs7.h>
52*9781SMoriah.Waterland@Sun.COM #include <openssl/err.h>
53*9781SMoriah.Waterland@Sun.COM #include <openssl/pem.h>
54*9781SMoriah.Waterland@Sun.COM #include "pkginfo.h"
55*9781SMoriah.Waterland@Sun.COM #include "pkgstrct.h"
56*9781SMoriah.Waterland@Sun.COM #include "pkgtrans.h"
57*9781SMoriah.Waterland@Sun.COM #include "pkgdev.h"
58*9781SMoriah.Waterland@Sun.COM #include "pkglib.h"
59*9781SMoriah.Waterland@Sun.COM #include "pkglibmsgs.h"
60*9781SMoriah.Waterland@Sun.COM #include "keystore.h"
61*9781SMoriah.Waterland@Sun.COM #include "pkglocale.h"
62*9781SMoriah.Waterland@Sun.COM #include "pkgerr.h"
63*9781SMoriah.Waterland@Sun.COM
64*9781SMoriah.Waterland@Sun.COM extern char *pkgdir; /* pkgparam.c */
65*9781SMoriah.Waterland@Sun.COM
66*9781SMoriah.Waterland@Sun.COM /* libadm.a */
67*9781SMoriah.Waterland@Sun.COM extern char *devattr(char *device, char *attribute);
68*9781SMoriah.Waterland@Sun.COM extern char *fpkginst(char *pkg, ...);
69*9781SMoriah.Waterland@Sun.COM extern int fpkginfo(struct pkginfo *info, char *pkginst);
70*9781SMoriah.Waterland@Sun.COM extern int getvol(char *device, char *label, int options, char *prompt);
71*9781SMoriah.Waterland@Sun.COM extern int _getvol(char *device, char *label, int options, char *prompt,
72*9781SMoriah.Waterland@Sun.COM char *norewind);
73*9781SMoriah.Waterland@Sun.COM
74*9781SMoriah.Waterland@Sun.COM /* dstream.c */
75*9781SMoriah.Waterland@Sun.COM extern int ds_ginit(char *device);
76*9781SMoriah.Waterland@Sun.COM extern int ds_close(int pkgendflg);
77*9781SMoriah.Waterland@Sun.COM
78*9781SMoriah.Waterland@Sun.COM #define CPIOPROC "/usr/bin/cpio"
79*9781SMoriah.Waterland@Sun.COM
80*9781SMoriah.Waterland@Sun.COM #define CMDSIZE 512 /* command block size */
81*9781SMoriah.Waterland@Sun.COM
82*9781SMoriah.Waterland@Sun.COM #define BLK_SIZE 512 /* size of logical block */
83*9781SMoriah.Waterland@Sun.COM
84*9781SMoriah.Waterland@Sun.COM #define ENTRY_MAX 256 /* max size of entry for cpio cmd or header */
85*9781SMoriah.Waterland@Sun.COM
86*9781SMoriah.Waterland@Sun.COM #define PKGINFO "pkginfo"
87*9781SMoriah.Waterland@Sun.COM #define PKGMAP "pkgmap"
88*9781SMoriah.Waterland@Sun.COM #define MAP_STAT_SIZE 60 /* 1st line of pkgmap (3 numbers & a : */
89*9781SMoriah.Waterland@Sun.COM
90*9781SMoriah.Waterland@Sun.COM #define INSTALL "install"
91*9781SMoriah.Waterland@Sun.COM #define RELOC "reloc"
92*9781SMoriah.Waterland@Sun.COM #define ROOT "root"
93*9781SMoriah.Waterland@Sun.COM #define ARCHIVE "archive"
94*9781SMoriah.Waterland@Sun.COM
95*9781SMoriah.Waterland@Sun.COM static struct pkgdev srcdev, dstdev;
96*9781SMoriah.Waterland@Sun.COM static char *tmpdir;
97*9781SMoriah.Waterland@Sun.COM static char *tmppath;
98*9781SMoriah.Waterland@Sun.COM static char *tmpsymdir = NULL;
99*9781SMoriah.Waterland@Sun.COM static char dstinst[NON_ABI_NAMELNGTH];
100*9781SMoriah.Waterland@Sun.COM static char *ids_name, *ods_name;
101*9781SMoriah.Waterland@Sun.COM static int ds_volcnt;
102*9781SMoriah.Waterland@Sun.COM static int ds_volno;
103*9781SMoriah.Waterland@Sun.COM static int compressedsize, has_comp_size;
104*9781SMoriah.Waterland@Sun.COM
105*9781SMoriah.Waterland@Sun.COM static void (*sigintHandler)();
106*9781SMoriah.Waterland@Sun.COM static void (*sighupHandler)();
107*9781SMoriah.Waterland@Sun.COM static void cleanup(void);
108*9781SMoriah.Waterland@Sun.COM static void sigtrap(int signo);
109*9781SMoriah.Waterland@Sun.COM static int rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize);
110*9781SMoriah.Waterland@Sun.COM
111*9781SMoriah.Waterland@Sun.COM static int cat_and_count(struct dm_buf *, char *);
112*9781SMoriah.Waterland@Sun.COM
113*9781SMoriah.Waterland@Sun.COM static int ckoverwrite(char *dir, char *inst, int options);
114*9781SMoriah.Waterland@Sun.COM static int pkgxfer(char *srcinst, int options);
115*9781SMoriah.Waterland@Sun.COM static int wdsheader(struct dm_buf *, char *src, char *device,
116*9781SMoriah.Waterland@Sun.COM char **pkg, PKCS7 *);
117*9781SMoriah.Waterland@Sun.COM static struct dm_buf *genheader(char *, char *, char **);
118*9781SMoriah.Waterland@Sun.COM
119*9781SMoriah.Waterland@Sun.COM static int dump_hdr_and_pkgs(BIO *, struct dm_buf *, char **);
120*9781SMoriah.Waterland@Sun.COM
121*9781SMoriah.Waterland@Sun.COM extern int ds_fd; /* open file descriptor for data stream WHERE? */
122*9781SMoriah.Waterland@Sun.COM
123*9781SMoriah.Waterland@Sun.COM static char *root_names[] = {
124*9781SMoriah.Waterland@Sun.COM "root",
125*9781SMoriah.Waterland@Sun.COM "root.cpio",
126*9781SMoriah.Waterland@Sun.COM "root.Z",
127*9781SMoriah.Waterland@Sun.COM "root.cpio.Z",
128*9781SMoriah.Waterland@Sun.COM 0
129*9781SMoriah.Waterland@Sun.COM };
130*9781SMoriah.Waterland@Sun.COM
131*9781SMoriah.Waterland@Sun.COM static char *reloc_names[] = {
132*9781SMoriah.Waterland@Sun.COM "reloc",
133*9781SMoriah.Waterland@Sun.COM "reloc.cpio",
134*9781SMoriah.Waterland@Sun.COM "reloc.Z",
135*9781SMoriah.Waterland@Sun.COM "reloc.cpio.Z",
136*9781SMoriah.Waterland@Sun.COM 0
137*9781SMoriah.Waterland@Sun.COM };
138*9781SMoriah.Waterland@Sun.COM
139*9781SMoriah.Waterland@Sun.COM static int signal_received = 0;
140*9781SMoriah.Waterland@Sun.COM
141*9781SMoriah.Waterland@Sun.COM char **xpkg; /* array of transferred packages */
142*9781SMoriah.Waterland@Sun.COM int nxpkg;
143*9781SMoriah.Waterland@Sun.COM
144*9781SMoriah.Waterland@Sun.COM static char *allpkg[] = {
145*9781SMoriah.Waterland@Sun.COM "all",
146*9781SMoriah.Waterland@Sun.COM NULL
147*9781SMoriah.Waterland@Sun.COM };
148*9781SMoriah.Waterland@Sun.COM
149*9781SMoriah.Waterland@Sun.COM static struct dm_buf hdrbuf;
150*9781SMoriah.Waterland@Sun.COM static char *pinput, *nextpinput;
151*9781SMoriah.Waterland@Sun.COM
152*9781SMoriah.Waterland@Sun.COM int
pkghead(char * device)153*9781SMoriah.Waterland@Sun.COM pkghead(char *device)
154*9781SMoriah.Waterland@Sun.COM {
155*9781SMoriah.Waterland@Sun.COM char *pt;
156*9781SMoriah.Waterland@Sun.COM int n;
157*9781SMoriah.Waterland@Sun.COM
158*9781SMoriah.Waterland@Sun.COM cleanup();
159*9781SMoriah.Waterland@Sun.COM
160*9781SMoriah.Waterland@Sun.COM
161*9781SMoriah.Waterland@Sun.COM if (device == NULL)
162*9781SMoriah.Waterland@Sun.COM return (0);
163*9781SMoriah.Waterland@Sun.COM else if ((device[0] == '/') && !isdir(device)) {
164*9781SMoriah.Waterland@Sun.COM pkgdir = device;
165*9781SMoriah.Waterland@Sun.COM return (0);
166*9781SMoriah.Waterland@Sun.COM } else if ((pt = devattr(device, "pathname")) != NULL && !isdir(pt)) {
167*9781SMoriah.Waterland@Sun.COM pkgdir = pt;
168*9781SMoriah.Waterland@Sun.COM return (0);
169*9781SMoriah.Waterland@Sun.COM }
170*9781SMoriah.Waterland@Sun.COM
171*9781SMoriah.Waterland@Sun.COM /* check for datastream */
172*9781SMoriah.Waterland@Sun.COM if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY,
173*9781SMoriah.Waterland@Sun.COM NULL, NULL)) {
174*9781SMoriah.Waterland@Sun.COM cleanup();
175*9781SMoriah.Waterland@Sun.COM return (n);
176*9781SMoriah.Waterland@Sun.COM }
177*9781SMoriah.Waterland@Sun.COM /* pkgtrans has set pkgdir */
178*9781SMoriah.Waterland@Sun.COM return (0);
179*9781SMoriah.Waterland@Sun.COM }
180*9781SMoriah.Waterland@Sun.COM
181*9781SMoriah.Waterland@Sun.COM static char *
mgets(char * buf,int size)182*9781SMoriah.Waterland@Sun.COM mgets(char *buf, int size)
183*9781SMoriah.Waterland@Sun.COM {
184*9781SMoriah.Waterland@Sun.COM nextpinput = strchr(pinput, '\n');
185*9781SMoriah.Waterland@Sun.COM if (nextpinput == NULL)
186*9781SMoriah.Waterland@Sun.COM return (0);
187*9781SMoriah.Waterland@Sun.COM *nextpinput = '\0';
188*9781SMoriah.Waterland@Sun.COM if ((int)strlen(pinput) > size)
189*9781SMoriah.Waterland@Sun.COM return (0);
190*9781SMoriah.Waterland@Sun.COM (void) strncpy(buf, pinput, strlen(pinput));
191*9781SMoriah.Waterland@Sun.COM buf[strlen(pinput)] = '\0';
192*9781SMoriah.Waterland@Sun.COM pinput = nextpinput + 1;
193*9781SMoriah.Waterland@Sun.COM return (buf);
194*9781SMoriah.Waterland@Sun.COM }
195*9781SMoriah.Waterland@Sun.COM /*
196*9781SMoriah.Waterland@Sun.COM * Here we construct the package size summaries for the headers. The
197*9781SMoriah.Waterland@Sun.COM * pkgmap file associated with fp must be rewound to the beginning of the
198*9781SMoriah.Waterland@Sun.COM * file. Note that we read three values from pkgmap first line in order
199*9781SMoriah.Waterland@Sun.COM * to get the *actual* size if this package is compressed.
200*9781SMoriah.Waterland@Sun.COM * This returns
201*9781SMoriah.Waterland@Sun.COM * 0 : error
202*9781SMoriah.Waterland@Sun.COM * 2 : not a compressed package
203*9781SMoriah.Waterland@Sun.COM * 3 : compressed package
204*9781SMoriah.Waterland@Sun.COM * and sets has_comp_size to indicate whether or not this is a compressed
205*9781SMoriah.Waterland@Sun.COM * package.
206*9781SMoriah.Waterland@Sun.COM */
207*9781SMoriah.Waterland@Sun.COM static int
rd_map_size(FILE * fp,int * npts,int * maxpsz,int * cmpsize)208*9781SMoriah.Waterland@Sun.COM rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize)
209*9781SMoriah.Waterland@Sun.COM {
210*9781SMoriah.Waterland@Sun.COM int n;
211*9781SMoriah.Waterland@Sun.COM char line_buffer[MAP_STAT_SIZE];
212*9781SMoriah.Waterland@Sun.COM
213*9781SMoriah.Waterland@Sun.COM /* First read the null terminated first line */
214*9781SMoriah.Waterland@Sun.COM if (fgets(line_buffer, MAP_STAT_SIZE, fp) == NULL) {
215*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
216*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSIZE));
217*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
218*9781SMoriah.Waterland@Sun.COM ecleanup();
219*9781SMoriah.Waterland@Sun.COM return (0);
220*9781SMoriah.Waterland@Sun.COM }
221*9781SMoriah.Waterland@Sun.COM
222*9781SMoriah.Waterland@Sun.COM n = sscanf(line_buffer, ": %d %d %d", npts, maxpsz, cmpsize);
223*9781SMoriah.Waterland@Sun.COM
224*9781SMoriah.Waterland@Sun.COM if (n == 3) /* A valid compressed package entry */
225*9781SMoriah.Waterland@Sun.COM has_comp_size = 1;
226*9781SMoriah.Waterland@Sun.COM else if (n == 2) /* A valid standard package entry */
227*9781SMoriah.Waterland@Sun.COM has_comp_size = 0;
228*9781SMoriah.Waterland@Sun.COM else { /* invalid entry */
229*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
230*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSIZE));
231*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
232*9781SMoriah.Waterland@Sun.COM ecleanup();
233*9781SMoriah.Waterland@Sun.COM return (0);
234*9781SMoriah.Waterland@Sun.COM }
235*9781SMoriah.Waterland@Sun.COM
236*9781SMoriah.Waterland@Sun.COM return (n);
237*9781SMoriah.Waterland@Sun.COM }
238*9781SMoriah.Waterland@Sun.COM
239*9781SMoriah.Waterland@Sun.COM /* will return 0, 1, 3, or 99 */
240*9781SMoriah.Waterland@Sun.COM static int
_pkgtrans(char * device1,char * device2,char ** pkg,int options,keystore_handle_t keystore,char * keystore_alias)241*9781SMoriah.Waterland@Sun.COM _pkgtrans(char *device1, char *device2, char **pkg, int options,
242*9781SMoriah.Waterland@Sun.COM keystore_handle_t keystore, char *keystore_alias)
243*9781SMoriah.Waterland@Sun.COM {
244*9781SMoriah.Waterland@Sun.COM BIO *p7_bio = NULL;
245*9781SMoriah.Waterland@Sun.COM EVP_PKEY *privkey = NULL;
246*9781SMoriah.Waterland@Sun.COM PKCS7 *sec_pkcs7 = NULL;
247*9781SMoriah.Waterland@Sun.COM PKCS7_SIGNER_INFO *sec_signerinfo = NULL;
248*9781SMoriah.Waterland@Sun.COM PKG_ERR *err;
249*9781SMoriah.Waterland@Sun.COM STACK_OF(X509) *cacerts = NULL;
250*9781SMoriah.Waterland@Sun.COM STACK_OF(X509) *clcerts = NULL;
251*9781SMoriah.Waterland@Sun.COM STACK_OF(X509) *sec_chain = NULL;
252*9781SMoriah.Waterland@Sun.COM X509 *pubcert = NULL;
253*9781SMoriah.Waterland@Sun.COM boolean_t making_sig = B_FALSE;
254*9781SMoriah.Waterland@Sun.COM char *src, *dst;
255*9781SMoriah.Waterland@Sun.COM int errflg, i, n;
256*9781SMoriah.Waterland@Sun.COM struct dm_buf *hdr;
257*9781SMoriah.Waterland@Sun.COM
258*9781SMoriah.Waterland@Sun.COM making_sig = (keystore != NULL) ? B_TRUE : B_FALSE;
259*9781SMoriah.Waterland@Sun.COM
260*9781SMoriah.Waterland@Sun.COM if (making_sig) {
261*9781SMoriah.Waterland@Sun.COM
262*9781SMoriah.Waterland@Sun.COM /* new error object */
263*9781SMoriah.Waterland@Sun.COM err = pkgerr_new();
264*9781SMoriah.Waterland@Sun.COM
265*9781SMoriah.Waterland@Sun.COM /* find matching cert and key */
266*9781SMoriah.Waterland@Sun.COM if (find_key_cert_pair(err, keystore,
267*9781SMoriah.Waterland@Sun.COM keystore_alias, &privkey, &pubcert) != 0) {
268*9781SMoriah.Waterland@Sun.COM pkgerr(err);
269*9781SMoriah.Waterland@Sun.COM pkgerr_free(err);
270*9781SMoriah.Waterland@Sun.COM return (1);
271*9781SMoriah.Waterland@Sun.COM }
272*9781SMoriah.Waterland@Sun.COM
273*9781SMoriah.Waterland@Sun.COM /* get CA certificates */
274*9781SMoriah.Waterland@Sun.COM if (find_ca_certs(err, keystore, &cacerts) != 0) {
275*9781SMoriah.Waterland@Sun.COM pkgerr(err);
276*9781SMoriah.Waterland@Sun.COM pkgerr_free(err);
277*9781SMoriah.Waterland@Sun.COM return (1);
278*9781SMoriah.Waterland@Sun.COM }
279*9781SMoriah.Waterland@Sun.COM
280*9781SMoriah.Waterland@Sun.COM /* get CL (aka "chain") certificates */
281*9781SMoriah.Waterland@Sun.COM if (find_cl_certs(err, keystore, &clcerts) != 0) {
282*9781SMoriah.Waterland@Sun.COM pkgerr(err);
283*9781SMoriah.Waterland@Sun.COM pkgerr_free(err);
284*9781SMoriah.Waterland@Sun.COM return (1);
285*9781SMoriah.Waterland@Sun.COM }
286*9781SMoriah.Waterland@Sun.COM
287*9781SMoriah.Waterland@Sun.COM /* initialize PKCS7 object to be filled in later */
288*9781SMoriah.Waterland@Sun.COM sec_pkcs7 = PKCS7_new();
289*9781SMoriah.Waterland@Sun.COM PKCS7_set_type(sec_pkcs7, NID_pkcs7_signed);
290*9781SMoriah.Waterland@Sun.COM sec_signerinfo = PKCS7_add_signature(sec_pkcs7,
291*9781SMoriah.Waterland@Sun.COM pubcert, privkey, EVP_sha1());
292*9781SMoriah.Waterland@Sun.COM
293*9781SMoriah.Waterland@Sun.COM if (sec_signerinfo == NULL) {
294*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_SEC), keystore_alias);
295*9781SMoriah.Waterland@Sun.COM ERR_print_errors_fp(stderr);
296*9781SMoriah.Waterland@Sun.COM pkgerr_free(err);
297*9781SMoriah.Waterland@Sun.COM return (1);
298*9781SMoriah.Waterland@Sun.COM }
299*9781SMoriah.Waterland@Sun.COM
300*9781SMoriah.Waterland@Sun.COM /* add signer cert into signature */
301*9781SMoriah.Waterland@Sun.COM PKCS7_add_certificate(sec_pkcs7, pubcert);
302*9781SMoriah.Waterland@Sun.COM
303*9781SMoriah.Waterland@Sun.COM /* attempt to resolve cert chain starting at the signer cert */
304*9781SMoriah.Waterland@Sun.COM if (get_cert_chain(err, pubcert, clcerts, cacerts,
305*9781SMoriah.Waterland@Sun.COM &sec_chain) != 0) {
306*9781SMoriah.Waterland@Sun.COM pkgerr(err);
307*9781SMoriah.Waterland@Sun.COM pkgerr_free(err);
308*9781SMoriah.Waterland@Sun.COM return (1);
309*9781SMoriah.Waterland@Sun.COM }
310*9781SMoriah.Waterland@Sun.COM
311*9781SMoriah.Waterland@Sun.COM /*
312*9781SMoriah.Waterland@Sun.COM * add the verification chain of certs into the signature.
313*9781SMoriah.Waterland@Sun.COM * The first cert is the user cert, which we don't need,
314*9781SMoriah.Waterland@Sun.COM * since it's baked in already, so skip it
315*9781SMoriah.Waterland@Sun.COM */
316*9781SMoriah.Waterland@Sun.COM for (i = 1; i < sk_X509_num(sec_chain); i++) {
317*9781SMoriah.Waterland@Sun.COM PKCS7_add_certificate(sec_pkcs7,
318*9781SMoriah.Waterland@Sun.COM sk_X509_value(sec_chain, i));
319*9781SMoriah.Waterland@Sun.COM }
320*9781SMoriah.Waterland@Sun.COM
321*9781SMoriah.Waterland@Sun.COM pkgerr_free(err);
322*9781SMoriah.Waterland@Sun.COM err = NULL;
323*9781SMoriah.Waterland@Sun.COM }
324*9781SMoriah.Waterland@Sun.COM
325*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
326*9781SMoriah.Waterland@Sun.COM return (1);
327*9781SMoriah.Waterland@Sun.COM }
328*9781SMoriah.Waterland@Sun.COM
329*9781SMoriah.Waterland@Sun.COM /* transfer spool to appropriate device */
330*9781SMoriah.Waterland@Sun.COM if (devtype(device1, &srcdev)) {
331*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
332*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_BADDEV), device1);
333*9781SMoriah.Waterland@Sun.COM return (1);
334*9781SMoriah.Waterland@Sun.COM }
335*9781SMoriah.Waterland@Sun.COM srcdev.rdonly++;
336*9781SMoriah.Waterland@Sun.COM
337*9781SMoriah.Waterland@Sun.COM /* check for datastream */
338*9781SMoriah.Waterland@Sun.COM ids_name = NULL;
339*9781SMoriah.Waterland@Sun.COM if (srcdev.bdevice) {
340*9781SMoriah.Waterland@Sun.COM if (n = _getvol(srcdev.bdevice, NULL, NULL,
341*9781SMoriah.Waterland@Sun.COM pkg_gt("Insert %v into %p."), srcdev.norewind)) {
342*9781SMoriah.Waterland@Sun.COM cleanup();
343*9781SMoriah.Waterland@Sun.COM if (n == 3)
344*9781SMoriah.Waterland@Sun.COM return (3);
345*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
346*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_GETVOL));
347*9781SMoriah.Waterland@Sun.COM return (1);
348*9781SMoriah.Waterland@Sun.COM }
349*9781SMoriah.Waterland@Sun.COM if (ds_readbuf(srcdev.cdevice))
350*9781SMoriah.Waterland@Sun.COM ids_name = srcdev.cdevice;
351*9781SMoriah.Waterland@Sun.COM }
352*9781SMoriah.Waterland@Sun.COM
353*9781SMoriah.Waterland@Sun.COM if (srcdev.cdevice && !srcdev.bdevice)
354*9781SMoriah.Waterland@Sun.COM ids_name = srcdev.cdevice;
355*9781SMoriah.Waterland@Sun.COM else if (srcdev.pathname) {
356*9781SMoriah.Waterland@Sun.COM ids_name = srcdev.pathname;
357*9781SMoriah.Waterland@Sun.COM if (access(ids_name, 0) == -1) {
358*9781SMoriah.Waterland@Sun.COM progerr(ERR_TRANSFER);
359*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_GETVOL));
360*9781SMoriah.Waterland@Sun.COM return (1);
361*9781SMoriah.Waterland@Sun.COM }
362*9781SMoriah.Waterland@Sun.COM }
363*9781SMoriah.Waterland@Sun.COM
364*9781SMoriah.Waterland@Sun.COM if (!ids_name && device2 == (char *)0) {
365*9781SMoriah.Waterland@Sun.COM if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) {
366*9781SMoriah.Waterland@Sun.COM cleanup();
367*9781SMoriah.Waterland@Sun.COM return (n);
368*9781SMoriah.Waterland@Sun.COM }
369*9781SMoriah.Waterland@Sun.COM if (srcdev.mount && *srcdev.mount)
370*9781SMoriah.Waterland@Sun.COM pkgdir = strdup(srcdev.mount);
371*9781SMoriah.Waterland@Sun.COM return (0);
372*9781SMoriah.Waterland@Sun.COM }
373*9781SMoriah.Waterland@Sun.COM
374*9781SMoriah.Waterland@Sun.COM if (ids_name && device2 == (char *)0) {
375*9781SMoriah.Waterland@Sun.COM tmppath = tmpnam(NULL);
376*9781SMoriah.Waterland@Sun.COM tmppath = strdup(tmppath);
377*9781SMoriah.Waterland@Sun.COM if (tmppath == NULL) {
378*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
379*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
380*9781SMoriah.Waterland@Sun.COM return (1);
381*9781SMoriah.Waterland@Sun.COM }
382*9781SMoriah.Waterland@Sun.COM if (mkdir(tmppath, 0755)) {
383*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
384*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MKDIR), tmppath);
385*9781SMoriah.Waterland@Sun.COM return (1);
386*9781SMoriah.Waterland@Sun.COM }
387*9781SMoriah.Waterland@Sun.COM device2 = tmppath;
388*9781SMoriah.Waterland@Sun.COM }
389*9781SMoriah.Waterland@Sun.COM
390*9781SMoriah.Waterland@Sun.COM if (devtype(device2, &dstdev)) {
391*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
392*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_BADDEV), device2);
393*9781SMoriah.Waterland@Sun.COM return (1);
394*9781SMoriah.Waterland@Sun.COM }
395*9781SMoriah.Waterland@Sun.COM
396*9781SMoriah.Waterland@Sun.COM if ((srcdev.cdevice && dstdev.cdevice) &&
397*9781SMoriah.Waterland@Sun.COM strcmp(srcdev.cdevice, dstdev.cdevice) == 0) {
398*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
399*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SAMEDEV));
400*9781SMoriah.Waterland@Sun.COM return (1);
401*9781SMoriah.Waterland@Sun.COM }
402*9781SMoriah.Waterland@Sun.COM
403*9781SMoriah.Waterland@Sun.COM ods_name = NULL;
404*9781SMoriah.Waterland@Sun.COM if (dstdev.cdevice && !dstdev.bdevice || dstdev.pathname)
405*9781SMoriah.Waterland@Sun.COM options |= PT_ODTSTREAM;
406*9781SMoriah.Waterland@Sun.COM
407*9781SMoriah.Waterland@Sun.COM if (options & PT_ODTSTREAM) {
408*9781SMoriah.Waterland@Sun.COM if (!((ods_name = dstdev.cdevice) != NULL ||
409*9781SMoriah.Waterland@Sun.COM (ods_name = dstdev.pathname) != NULL)) {
410*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
411*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_BADDEV), device2);
412*9781SMoriah.Waterland@Sun.COM return (1);
413*9781SMoriah.Waterland@Sun.COM }
414*9781SMoriah.Waterland@Sun.COM if (ids_name) {
415*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
416*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_TWODSTREAM));
417*9781SMoriah.Waterland@Sun.COM return (1);
418*9781SMoriah.Waterland@Sun.COM }
419*9781SMoriah.Waterland@Sun.COM } else {
420*9781SMoriah.Waterland@Sun.COM /*
421*9781SMoriah.Waterland@Sun.COM * output device isn't a stream. If we're making a signed
422*9781SMoriah.Waterland@Sun.COM * package, then fail, since we can't make signed,
423*9781SMoriah.Waterland@Sun.COM * non-stream pkgs
424*9781SMoriah.Waterland@Sun.COM */
425*9781SMoriah.Waterland@Sun.COM if (making_sig) {
426*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
427*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(ERR_CANTSIGN));
428*9781SMoriah.Waterland@Sun.COM return (1);
429*9781SMoriah.Waterland@Sun.COM }
430*9781SMoriah.Waterland@Sun.COM }
431*9781SMoriah.Waterland@Sun.COM
432*9781SMoriah.Waterland@Sun.COM if ((srcdev.dirname && dstdev.dirname) &&
433*9781SMoriah.Waterland@Sun.COM strcmp(srcdev.dirname, dstdev.dirname) == 0) {
434*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
435*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SAMEDEV));
436*9781SMoriah.Waterland@Sun.COM return (1);
437*9781SMoriah.Waterland@Sun.COM }
438*9781SMoriah.Waterland@Sun.COM
439*9781SMoriah.Waterland@Sun.COM if ((srcdev.pathname && dstdev.pathname) &&
440*9781SMoriah.Waterland@Sun.COM strcmp(srcdev.pathname, dstdev.pathname) == 0) {
441*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
442*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SAMEDEV));
443*9781SMoriah.Waterland@Sun.COM return (1);
444*9781SMoriah.Waterland@Sun.COM }
445*9781SMoriah.Waterland@Sun.COM
446*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
447*9781SMoriah.Waterland@Sun.COM return (1);
448*9781SMoriah.Waterland@Sun.COM }
449*9781SMoriah.Waterland@Sun.COM
450*9781SMoriah.Waterland@Sun.COM if (ids_name) {
451*9781SMoriah.Waterland@Sun.COM if (srcdev.cdevice && !srcdev.bdevice &&
452*9781SMoriah.Waterland@Sun.COM (n = _getvol(srcdev.cdevice, NULL, NULL, NULL,
453*9781SMoriah.Waterland@Sun.COM srcdev.norewind))) {
454*9781SMoriah.Waterland@Sun.COM cleanup();
455*9781SMoriah.Waterland@Sun.COM if (n == 3)
456*9781SMoriah.Waterland@Sun.COM return (3);
457*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
458*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_GETVOL));
459*9781SMoriah.Waterland@Sun.COM return (1);
460*9781SMoriah.Waterland@Sun.COM }
461*9781SMoriah.Waterland@Sun.COM if (srcdev.dirname = tmpnam(NULL))
462*9781SMoriah.Waterland@Sun.COM tmpdir = srcdev.dirname = strdup(srcdev.dirname);
463*9781SMoriah.Waterland@Sun.COM
464*9781SMoriah.Waterland@Sun.COM if ((srcdev.dirname == NULL) || mkdir(srcdev.dirname, 0755) ||
465*9781SMoriah.Waterland@Sun.COM chdir(srcdev.dirname)) {
466*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
467*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTEMP), srcdev.dirname);
468*9781SMoriah.Waterland@Sun.COM cleanup();
469*9781SMoriah.Waterland@Sun.COM return (1);
470*9781SMoriah.Waterland@Sun.COM }
471*9781SMoriah.Waterland@Sun.COM if (ds_init(ids_name, pkg, srcdev.norewind)) {
472*9781SMoriah.Waterland@Sun.COM cleanup();
473*9781SMoriah.Waterland@Sun.COM return (1);
474*9781SMoriah.Waterland@Sun.COM }
475*9781SMoriah.Waterland@Sun.COM } else if (srcdev.mount) {
476*9781SMoriah.Waterland@Sun.COM if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) {
477*9781SMoriah.Waterland@Sun.COM cleanup();
478*9781SMoriah.Waterland@Sun.COM return (n);
479*9781SMoriah.Waterland@Sun.COM }
480*9781SMoriah.Waterland@Sun.COM }
481*9781SMoriah.Waterland@Sun.COM
482*9781SMoriah.Waterland@Sun.COM src = srcdev.dirname;
483*9781SMoriah.Waterland@Sun.COM dst = dstdev.dirname;
484*9781SMoriah.Waterland@Sun.COM
485*9781SMoriah.Waterland@Sun.COM if (chdir(src)) {
486*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
487*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), src);
488*9781SMoriah.Waterland@Sun.COM cleanup();
489*9781SMoriah.Waterland@Sun.COM return (1);
490*9781SMoriah.Waterland@Sun.COM }
491*9781SMoriah.Waterland@Sun.COM
492*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
493*9781SMoriah.Waterland@Sun.COM return (1);
494*9781SMoriah.Waterland@Sun.COM }
495*9781SMoriah.Waterland@Sun.COM
496*9781SMoriah.Waterland@Sun.COM xpkg = pkg = gpkglist(src, pkg, NULL);
497*9781SMoriah.Waterland@Sun.COM if (!pkg) {
498*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
499*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOPKGS), src);
500*9781SMoriah.Waterland@Sun.COM cleanup();
501*9781SMoriah.Waterland@Sun.COM return (1);
502*9781SMoriah.Waterland@Sun.COM }
503*9781SMoriah.Waterland@Sun.COM
504*9781SMoriah.Waterland@Sun.COM for (nxpkg = 0; pkg[nxpkg]; /* void */) {
505*9781SMoriah.Waterland@Sun.COM nxpkg++; /* count */
506*9781SMoriah.Waterland@Sun.COM }
507*9781SMoriah.Waterland@Sun.COM
508*9781SMoriah.Waterland@Sun.COM if (ids_name) {
509*9781SMoriah.Waterland@Sun.COM ds_order(pkg); /* order requests */
510*9781SMoriah.Waterland@Sun.COM }
511*9781SMoriah.Waterland@Sun.COM
512*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
513*9781SMoriah.Waterland@Sun.COM return (1);
514*9781SMoriah.Waterland@Sun.COM }
515*9781SMoriah.Waterland@Sun.COM
516*9781SMoriah.Waterland@Sun.COM if (options & PT_ODTSTREAM) {
517*9781SMoriah.Waterland@Sun.COM char line[128];
518*9781SMoriah.Waterland@Sun.COM
519*9781SMoriah.Waterland@Sun.COM if (!dstdev.pathname &&
520*9781SMoriah.Waterland@Sun.COM (n = _getvol(ods_name, NULL, DM_FORMAT, NULL,
521*9781SMoriah.Waterland@Sun.COM dstdev.norewind))) {
522*9781SMoriah.Waterland@Sun.COM cleanup();
523*9781SMoriah.Waterland@Sun.COM if (n == 3)
524*9781SMoriah.Waterland@Sun.COM return (3);
525*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
526*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_GETVOL));
527*9781SMoriah.Waterland@Sun.COM return (1);
528*9781SMoriah.Waterland@Sun.COM }
529*9781SMoriah.Waterland@Sun.COM if ((hdr = genheader(src, ods_name, pkg)) == NULL) {
530*9781SMoriah.Waterland@Sun.COM cleanup();
531*9781SMoriah.Waterland@Sun.COM return (1);
532*9781SMoriah.Waterland@Sun.COM }
533*9781SMoriah.Waterland@Sun.COM if (making_sig) {
534*9781SMoriah.Waterland@Sun.COM /* start up signature data stream */
535*9781SMoriah.Waterland@Sun.COM PKCS7_content_new(sec_pkcs7, NID_pkcs7_data);
536*9781SMoriah.Waterland@Sun.COM PKCS7_set_detached(sec_pkcs7, 1);
537*9781SMoriah.Waterland@Sun.COM p7_bio = PKCS7_dataInit(sec_pkcs7, NULL);
538*9781SMoriah.Waterland@Sun.COM
539*9781SMoriah.Waterland@Sun.COM /*
540*9781SMoriah.Waterland@Sun.COM * Here we generate all the data that will go into
541*9781SMoriah.Waterland@Sun.COM * the package, and send it through the signature
542*9781SMoriah.Waterland@Sun.COM * generator, essentially calculating the signature
543*9781SMoriah.Waterland@Sun.COM * of the entire package so we can place it in the
544*9781SMoriah.Waterland@Sun.COM * header. Otherwise we'd have to place it at the end
545*9781SMoriah.Waterland@Sun.COM * of the pkg, which would break the ABI
546*9781SMoriah.Waterland@Sun.COM */
547*9781SMoriah.Waterland@Sun.COM if (!(options & PT_SILENT)) {
548*9781SMoriah.Waterland@Sun.COM (void) fprintf(stderr, pkg_gt(MSG_SIGNING),
549*9781SMoriah.Waterland@Sun.COM get_subject_display_name(pubcert));
550*9781SMoriah.Waterland@Sun.COM }
551*9781SMoriah.Waterland@Sun.COM if (dump_hdr_and_pkgs(p7_bio, hdr, pkg) != 0) {
552*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_NOGEN));
553*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_GETVOL));
554*9781SMoriah.Waterland@Sun.COM cleanup();
555*9781SMoriah.Waterland@Sun.COM return (1);
556*9781SMoriah.Waterland@Sun.COM
557*9781SMoriah.Waterland@Sun.COM }
558*9781SMoriah.Waterland@Sun.COM
559*9781SMoriah.Waterland@Sun.COM BIO_flush(p7_bio);
560*9781SMoriah.Waterland@Sun.COM
561*9781SMoriah.Waterland@Sun.COM /*
562*9781SMoriah.Waterland@Sun.COM * now generate PKCS7 signature
563*9781SMoriah.Waterland@Sun.COM */
564*9781SMoriah.Waterland@Sun.COM if (!PKCS7_dataFinal(sec_pkcs7, p7_bio)) {
565*9781SMoriah.Waterland@Sun.COM progerr(gettext(ERR_NOGEN));
566*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_GETVOL));
567*9781SMoriah.Waterland@Sun.COM cleanup();
568*9781SMoriah.Waterland@Sun.COM return (1);
569*9781SMoriah.Waterland@Sun.COM }
570*9781SMoriah.Waterland@Sun.COM
571*9781SMoriah.Waterland@Sun.COM BIO_free(p7_bio);
572*9781SMoriah.Waterland@Sun.COM }
573*9781SMoriah.Waterland@Sun.COM
574*9781SMoriah.Waterland@Sun.COM /* write out header to stream, which includes signature */
575*9781SMoriah.Waterland@Sun.COM if (wdsheader(hdr, src, ods_name, pkg, sec_pkcs7)) {
576*9781SMoriah.Waterland@Sun.COM cleanup();
577*9781SMoriah.Waterland@Sun.COM return (1);
578*9781SMoriah.Waterland@Sun.COM }
579*9781SMoriah.Waterland@Sun.COM
580*9781SMoriah.Waterland@Sun.COM if (sec_pkcs7 != NULL) {
581*9781SMoriah.Waterland@Sun.COM /* nuke in-memory signature for safety */
582*9781SMoriah.Waterland@Sun.COM PKCS7_free(sec_pkcs7);
583*9781SMoriah.Waterland@Sun.COM sec_pkcs7 = NULL;
584*9781SMoriah.Waterland@Sun.COM }
585*9781SMoriah.Waterland@Sun.COM
586*9781SMoriah.Waterland@Sun.COM ds_volno = 1; /* number of volumes in datastream */
587*9781SMoriah.Waterland@Sun.COM pinput = hdrbuf.text_buffer;
588*9781SMoriah.Waterland@Sun.COM /* skip past first line in header */
589*9781SMoriah.Waterland@Sun.COM (void) mgets(line, 128);
590*9781SMoriah.Waterland@Sun.COM }
591*9781SMoriah.Waterland@Sun.COM
592*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
593*9781SMoriah.Waterland@Sun.COM return (1);
594*9781SMoriah.Waterland@Sun.COM }
595*9781SMoriah.Waterland@Sun.COM
596*9781SMoriah.Waterland@Sun.COM errflg = 0;
597*9781SMoriah.Waterland@Sun.COM
598*9781SMoriah.Waterland@Sun.COM for (i = 0; pkg[i]; i++) {
599*9781SMoriah.Waterland@Sun.COM
600*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
601*9781SMoriah.Waterland@Sun.COM return (1);
602*9781SMoriah.Waterland@Sun.COM }
603*9781SMoriah.Waterland@Sun.COM
604*9781SMoriah.Waterland@Sun.COM if (!(options & PT_ODTSTREAM) && dstdev.mount) {
605*9781SMoriah.Waterland@Sun.COM if (n = pkgmount(&dstdev, NULL, 0, 0, 1)) {
606*9781SMoriah.Waterland@Sun.COM cleanup();
607*9781SMoriah.Waterland@Sun.COM return (n);
608*9781SMoriah.Waterland@Sun.COM }
609*9781SMoriah.Waterland@Sun.COM }
610*9781SMoriah.Waterland@Sun.COM if (errflg = pkgxfer(pkg[i], options)) {
611*9781SMoriah.Waterland@Sun.COM pkg[i] = NULL;
612*9781SMoriah.Waterland@Sun.COM if ((options & PT_ODTSTREAM) || (errflg != 2))
613*9781SMoriah.Waterland@Sun.COM break;
614*9781SMoriah.Waterland@Sun.COM } else if (strcmp(dstinst, pkg[i]))
615*9781SMoriah.Waterland@Sun.COM pkg[i] = strdup(dstinst);
616*9781SMoriah.Waterland@Sun.COM }
617*9781SMoriah.Waterland@Sun.COM
618*9781SMoriah.Waterland@Sun.COM if (!(options & PT_ODTSTREAM) && dst) {
619*9781SMoriah.Waterland@Sun.COM pkgdir = strdup(dst);
620*9781SMoriah.Waterland@Sun.COM }
621*9781SMoriah.Waterland@Sun.COM
622*9781SMoriah.Waterland@Sun.COM /*
623*9781SMoriah.Waterland@Sun.COM * No cleanup of temporary directories created in this
624*9781SMoriah.Waterland@Sun.COM * function is done here. The calling function must do
625*9781SMoriah.Waterland@Sun.COM * the cleanup.
626*9781SMoriah.Waterland@Sun.COM */
627*9781SMoriah.Waterland@Sun.COM
628*9781SMoriah.Waterland@Sun.COM return (signal_received > 0 ? 1 : errflg);
629*9781SMoriah.Waterland@Sun.COM }
630*9781SMoriah.Waterland@Sun.COM
631*9781SMoriah.Waterland@Sun.COM int
pkgtrans(char * device1,char * device2,char ** pkg,int options,keystore_handle_t keystore,char * keystore_alias)632*9781SMoriah.Waterland@Sun.COM pkgtrans(char *device1, char *device2, char **pkg, int options,
633*9781SMoriah.Waterland@Sun.COM keystore_handle_t keystore, char *keystore_alias)
634*9781SMoriah.Waterland@Sun.COM {
635*9781SMoriah.Waterland@Sun.COM int r;
636*9781SMoriah.Waterland@Sun.COM struct sigaction nact;
637*9781SMoriah.Waterland@Sun.COM struct sigaction oact;
638*9781SMoriah.Waterland@Sun.COM
639*9781SMoriah.Waterland@Sun.COM /*
640*9781SMoriah.Waterland@Sun.COM * setup signal handlers for SIGINT and SIGHUP and release hold
641*9781SMoriah.Waterland@Sun.COM */
642*9781SMoriah.Waterland@Sun.COM
643*9781SMoriah.Waterland@Sun.COM /* hold SIGINT/SIGHUP interrupts */
644*9781SMoriah.Waterland@Sun.COM
645*9781SMoriah.Waterland@Sun.COM (void) sighold(SIGHUP);
646*9781SMoriah.Waterland@Sun.COM (void) sighold(SIGINT);
647*9781SMoriah.Waterland@Sun.COM
648*9781SMoriah.Waterland@Sun.COM /* hook SIGINT to sigtrap */
649*9781SMoriah.Waterland@Sun.COM
650*9781SMoriah.Waterland@Sun.COM nact.sa_handler = sigtrap;
651*9781SMoriah.Waterland@Sun.COM nact.sa_flags = SA_RESTART;
652*9781SMoriah.Waterland@Sun.COM (void) sigemptyset(&nact.sa_mask);
653*9781SMoriah.Waterland@Sun.COM
654*9781SMoriah.Waterland@Sun.COM if (sigaction(SIGINT, &nact, &oact) < 0) {
655*9781SMoriah.Waterland@Sun.COM sigintHandler = SIG_DFL;
656*9781SMoriah.Waterland@Sun.COM } else {
657*9781SMoriah.Waterland@Sun.COM sigintHandler = oact.sa_handler;
658*9781SMoriah.Waterland@Sun.COM }
659*9781SMoriah.Waterland@Sun.COM
660*9781SMoriah.Waterland@Sun.COM /* hook SIGHUP to sigtrap */
661*9781SMoriah.Waterland@Sun.COM
662*9781SMoriah.Waterland@Sun.COM nact.sa_handler = sigtrap;
663*9781SMoriah.Waterland@Sun.COM nact.sa_flags = SA_RESTART;
664*9781SMoriah.Waterland@Sun.COM (void) sigemptyset(&nact.sa_mask);
665*9781SMoriah.Waterland@Sun.COM
666*9781SMoriah.Waterland@Sun.COM if (sigaction(SIGHUP, &nact, &oact) < 0) {
667*9781SMoriah.Waterland@Sun.COM sighupHandler = SIG_DFL;
668*9781SMoriah.Waterland@Sun.COM } else {
669*9781SMoriah.Waterland@Sun.COM sighupHandler = oact.sa_handler;
670*9781SMoriah.Waterland@Sun.COM }
671*9781SMoriah.Waterland@Sun.COM
672*9781SMoriah.Waterland@Sun.COM /* reset signal received count */
673*9781SMoriah.Waterland@Sun.COM
674*9781SMoriah.Waterland@Sun.COM signal_received = 0;
675*9781SMoriah.Waterland@Sun.COM
676*9781SMoriah.Waterland@Sun.COM /* release hold on signals */
677*9781SMoriah.Waterland@Sun.COM
678*9781SMoriah.Waterland@Sun.COM (void) sigrelse(SIGHUP);
679*9781SMoriah.Waterland@Sun.COM (void) sigrelse(SIGINT);
680*9781SMoriah.Waterland@Sun.COM
681*9781SMoriah.Waterland@Sun.COM /*
682*9781SMoriah.Waterland@Sun.COM * perform the package translation
683*9781SMoriah.Waterland@Sun.COM */
684*9781SMoriah.Waterland@Sun.COM
685*9781SMoriah.Waterland@Sun.COM r = _pkgtrans(device1, device2, pkg, options, keystore, keystore_alias);
686*9781SMoriah.Waterland@Sun.COM
687*9781SMoriah.Waterland@Sun.COM /*
688*9781SMoriah.Waterland@Sun.COM * reset signal handlers
689*9781SMoriah.Waterland@Sun.COM */
690*9781SMoriah.Waterland@Sun.COM
691*9781SMoriah.Waterland@Sun.COM /* hold SIGINT/SIGHUP interrupts */
692*9781SMoriah.Waterland@Sun.COM
693*9781SMoriah.Waterland@Sun.COM (void) sighold(SIGHUP);
694*9781SMoriah.Waterland@Sun.COM (void) sighold(SIGINT);
695*9781SMoriah.Waterland@Sun.COM
696*9781SMoriah.Waterland@Sun.COM /* reset SIGINT */
697*9781SMoriah.Waterland@Sun.COM
698*9781SMoriah.Waterland@Sun.COM nact.sa_handler = sigintHandler;
699*9781SMoriah.Waterland@Sun.COM nact.sa_flags = SA_RESTART;
700*9781SMoriah.Waterland@Sun.COM (void) sigemptyset(&nact.sa_mask);
701*9781SMoriah.Waterland@Sun.COM
702*9781SMoriah.Waterland@Sun.COM (void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);
703*9781SMoriah.Waterland@Sun.COM
704*9781SMoriah.Waterland@Sun.COM /* reset SIGHUP */
705*9781SMoriah.Waterland@Sun.COM
706*9781SMoriah.Waterland@Sun.COM nact.sa_handler = sighupHandler;
707*9781SMoriah.Waterland@Sun.COM nact.sa_flags = SA_RESTART;
708*9781SMoriah.Waterland@Sun.COM (void) sigemptyset(&nact.sa_mask);
709*9781SMoriah.Waterland@Sun.COM
710*9781SMoriah.Waterland@Sun.COM (void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);
711*9781SMoriah.Waterland@Sun.COM
712*9781SMoriah.Waterland@Sun.COM /* if signal received and pkgtrans returned error, call cleanup */
713*9781SMoriah.Waterland@Sun.COM
714*9781SMoriah.Waterland@Sun.COM if (signal_received > 0) {
715*9781SMoriah.Waterland@Sun.COM if (r != 0) {
716*9781SMoriah.Waterland@Sun.COM cleanup();
717*9781SMoriah.Waterland@Sun.COM }
718*9781SMoriah.Waterland@Sun.COM (void) kill(getpid(), SIGINT);
719*9781SMoriah.Waterland@Sun.COM }
720*9781SMoriah.Waterland@Sun.COM
721*9781SMoriah.Waterland@Sun.COM /* release hold on signals */
722*9781SMoriah.Waterland@Sun.COM
723*9781SMoriah.Waterland@Sun.COM (void) sigrelse(SIGHUP);
724*9781SMoriah.Waterland@Sun.COM (void) sigrelse(SIGINT);
725*9781SMoriah.Waterland@Sun.COM
726*9781SMoriah.Waterland@Sun.COM return (r);
727*9781SMoriah.Waterland@Sun.COM }
728*9781SMoriah.Waterland@Sun.COM
729*9781SMoriah.Waterland@Sun.COM /*
730*9781SMoriah.Waterland@Sun.COM * This function concatenates append to the text described in the buf_ctrl
731*9781SMoriah.Waterland@Sun.COM * structure. This code modifies data in this structure and handles all
732*9781SMoriah.Waterland@Sun.COM * allocation issues. It returns '0' if everything was successful and '1'
733*9781SMoriah.Waterland@Sun.COM * if not.
734*9781SMoriah.Waterland@Sun.COM */
735*9781SMoriah.Waterland@Sun.COM static int
cat_and_count(struct dm_buf * buf_ctrl,char * append)736*9781SMoriah.Waterland@Sun.COM cat_and_count(struct dm_buf *buf_ctrl, char *append)
737*9781SMoriah.Waterland@Sun.COM {
738*9781SMoriah.Waterland@Sun.COM
739*9781SMoriah.Waterland@Sun.COM /* keep allocating until we have enough room to hold string */
740*9781SMoriah.Waterland@Sun.COM while ((buf_ctrl->offset + (int)strlen(append))
741*9781SMoriah.Waterland@Sun.COM >= buf_ctrl->allocation) {
742*9781SMoriah.Waterland@Sun.COM /* reallocate (and maybe move) text buffer */
743*9781SMoriah.Waterland@Sun.COM if ((buf_ctrl->text_buffer =
744*9781SMoriah.Waterland@Sun.COM (char *)realloc(buf_ctrl->text_buffer,
745*9781SMoriah.Waterland@Sun.COM buf_ctrl->allocation + BLK_SIZE)) == NULL) {
746*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
747*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
748*9781SMoriah.Waterland@Sun.COM free(buf_ctrl->text_buffer);
749*9781SMoriah.Waterland@Sun.COM return (1);
750*9781SMoriah.Waterland@Sun.COM }
751*9781SMoriah.Waterland@Sun.COM
752*9781SMoriah.Waterland@Sun.COM /* clear the new memory */
753*9781SMoriah.Waterland@Sun.COM (void) memset(buf_ctrl->text_buffer +
754*9781SMoriah.Waterland@Sun.COM buf_ctrl->allocation, '\0', BLK_SIZE);
755*9781SMoriah.Waterland@Sun.COM
756*9781SMoriah.Waterland@Sun.COM /* adjust total allocation */
757*9781SMoriah.Waterland@Sun.COM buf_ctrl->allocation += BLK_SIZE;
758*9781SMoriah.Waterland@Sun.COM }
759*9781SMoriah.Waterland@Sun.COM
760*9781SMoriah.Waterland@Sun.COM /* append new string to end of buffer */
761*9781SMoriah.Waterland@Sun.COM while (*append) {
762*9781SMoriah.Waterland@Sun.COM *(buf_ctrl->text_buffer + buf_ctrl->offset) = *append++;
763*9781SMoriah.Waterland@Sun.COM (buf_ctrl->offset)++;
764*9781SMoriah.Waterland@Sun.COM }
765*9781SMoriah.Waterland@Sun.COM
766*9781SMoriah.Waterland@Sun.COM return (0);
767*9781SMoriah.Waterland@Sun.COM }
768*9781SMoriah.Waterland@Sun.COM
769*9781SMoriah.Waterland@Sun.COM static struct dm_buf *
genheader(char * src,char * device,char ** pkg)770*9781SMoriah.Waterland@Sun.COM genheader(char *src, char *device, char **pkg)
771*9781SMoriah.Waterland@Sun.COM {
772*9781SMoriah.Waterland@Sun.COM
773*9781SMoriah.Waterland@Sun.COM FILE *fp;
774*9781SMoriah.Waterland@Sun.COM char path[MAXPATHLEN], tmp_entry[ENTRY_MAX];
775*9781SMoriah.Waterland@Sun.COM int i, n, nparts, maxpsize;
776*9781SMoriah.Waterland@Sun.COM int partcnt, totsize;
777*9781SMoriah.Waterland@Sun.COM struct stat statbuf;
778*9781SMoriah.Waterland@Sun.COM
779*9781SMoriah.Waterland@Sun.COM if ((hdrbuf.text_buffer = (char *)malloc(BLK_SIZE)) == NULL) {
780*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
781*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
782*9781SMoriah.Waterland@Sun.COM return (NULL);
783*9781SMoriah.Waterland@Sun.COM }
784*9781SMoriah.Waterland@Sun.COM
785*9781SMoriah.Waterland@Sun.COM /* clear the new memory */
786*9781SMoriah.Waterland@Sun.COM (void) memset(hdrbuf.text_buffer, '\0', BLK_SIZE);
787*9781SMoriah.Waterland@Sun.COM
788*9781SMoriah.Waterland@Sun.COM /* set up the buffer control structure for the header */
789*9781SMoriah.Waterland@Sun.COM hdrbuf.offset = 0;
790*9781SMoriah.Waterland@Sun.COM hdrbuf.allocation = BLK_SIZE;
791*9781SMoriah.Waterland@Sun.COM
792*9781SMoriah.Waterland@Sun.COM (void) cat_and_count(&hdrbuf, HDR_PREFIX);
793*9781SMoriah.Waterland@Sun.COM (void) cat_and_count(&hdrbuf, "\n");
794*9781SMoriah.Waterland@Sun.COM
795*9781SMoriah.Waterland@Sun.COM nparts = maxpsize = 0;
796*9781SMoriah.Waterland@Sun.COM
797*9781SMoriah.Waterland@Sun.COM totsize = 0;
798*9781SMoriah.Waterland@Sun.COM for (i = 0; pkg[i]; i++) {
799*9781SMoriah.Waterland@Sun.COM (void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
800*9781SMoriah.Waterland@Sun.COM src, pkg[i], PKGINFO);
801*9781SMoriah.Waterland@Sun.COM if (stat(path, &statbuf) < 0) {
802*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
803*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_BADPKGINFO));
804*9781SMoriah.Waterland@Sun.COM ecleanup();
805*9781SMoriah.Waterland@Sun.COM return (NULL);
806*9781SMoriah.Waterland@Sun.COM }
807*9781SMoriah.Waterland@Sun.COM totsize += statbuf.st_size/BLK_SIZE + 1;
808*9781SMoriah.Waterland@Sun.COM }
809*9781SMoriah.Waterland@Sun.COM
810*9781SMoriah.Waterland@Sun.COM /*
811*9781SMoriah.Waterland@Sun.COM * totsize contains number of blocks used by the pkginfo files
812*9781SMoriah.Waterland@Sun.COM */
813*9781SMoriah.Waterland@Sun.COM totsize += i/4 + 1;
814*9781SMoriah.Waterland@Sun.COM if (dstdev.capacity && totsize > dstdev.capacity) {
815*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
816*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSPACE), totsize, dstdev.capacity);
817*9781SMoriah.Waterland@Sun.COM ecleanup();
818*9781SMoriah.Waterland@Sun.COM return (NULL);
819*9781SMoriah.Waterland@Sun.COM }
820*9781SMoriah.Waterland@Sun.COM
821*9781SMoriah.Waterland@Sun.COM ds_volcnt = 1;
822*9781SMoriah.Waterland@Sun.COM for (i = 0; pkg[i]; i++) {
823*9781SMoriah.Waterland@Sun.COM partcnt = 0;
824*9781SMoriah.Waterland@Sun.COM (void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
825*9781SMoriah.Waterland@Sun.COM src, pkg[i], PKGMAP);
826*9781SMoriah.Waterland@Sun.COM if ((fp = fopen(path, "r")) == NULL) {
827*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
828*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOPKGMAP), pkg[i]);
829*9781SMoriah.Waterland@Sun.COM ecleanup();
830*9781SMoriah.Waterland@Sun.COM return (NULL);
831*9781SMoriah.Waterland@Sun.COM }
832*9781SMoriah.Waterland@Sun.COM
833*9781SMoriah.Waterland@Sun.COM /* Evaluate the first entry in pkgmap */
834*9781SMoriah.Waterland@Sun.COM n = rd_map_size(fp, &nparts, &maxpsize, &compressedsize);
835*9781SMoriah.Waterland@Sun.COM
836*9781SMoriah.Waterland@Sun.COM if (n == 3) /* It's a compressed package */
837*9781SMoriah.Waterland@Sun.COM /* The header needs the *real* size */
838*9781SMoriah.Waterland@Sun.COM maxpsize = compressedsize;
839*9781SMoriah.Waterland@Sun.COM else if (n == 0) /* pkgmap is corrupt */
840*9781SMoriah.Waterland@Sun.COM return (NULL);
841*9781SMoriah.Waterland@Sun.COM
842*9781SMoriah.Waterland@Sun.COM if (dstdev.capacity && maxpsize > dstdev.capacity) {
843*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
844*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSPACE));
845*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
846*9781SMoriah.Waterland@Sun.COM ecleanup();
847*9781SMoriah.Waterland@Sun.COM return (NULL);
848*9781SMoriah.Waterland@Sun.COM }
849*9781SMoriah.Waterland@Sun.COM
850*9781SMoriah.Waterland@Sun.COM /* add pkg name, number of parts and the max part size */
851*9781SMoriah.Waterland@Sun.COM if (snprintf(tmp_entry, ENTRY_MAX, "%s %d %d",
852*9781SMoriah.Waterland@Sun.COM pkg[i], nparts, maxpsize) >= ENTRY_MAX) {
853*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
854*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(ERR_MEM));
855*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
856*9781SMoriah.Waterland@Sun.COM ecleanup();
857*9781SMoriah.Waterland@Sun.COM return (NULL);
858*9781SMoriah.Waterland@Sun.COM }
859*9781SMoriah.Waterland@Sun.COM if (cat_and_count(&hdrbuf, tmp_entry)) {
860*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
861*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
862*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
863*9781SMoriah.Waterland@Sun.COM ecleanup();
864*9781SMoriah.Waterland@Sun.COM return (NULL);
865*9781SMoriah.Waterland@Sun.COM }
866*9781SMoriah.Waterland@Sun.COM
867*9781SMoriah.Waterland@Sun.COM totsize += nparts * maxpsize;
868*9781SMoriah.Waterland@Sun.COM if (dstdev.capacity && dstdev.capacity < totsize) {
869*9781SMoriah.Waterland@Sun.COM int lastpartcnt = 0;
870*9781SMoriah.Waterland@Sun.COM #if 0
871*9781SMoriah.Waterland@Sun.COM if (i != 0) {
872*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
873*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSPACE));
874*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
875*9781SMoriah.Waterland@Sun.COM ecleanup();
876*9781SMoriah.Waterland@Sun.COM return (NULL);
877*9781SMoriah.Waterland@Sun.COM }
878*9781SMoriah.Waterland@Sun.COM #endif /* 0 */
879*9781SMoriah.Waterland@Sun.COM
880*9781SMoriah.Waterland@Sun.COM if (totsize)
881*9781SMoriah.Waterland@Sun.COM totsize -= nparts * maxpsize;
882*9781SMoriah.Waterland@Sun.COM while (partcnt < nparts) {
883*9781SMoriah.Waterland@Sun.COM while (totsize <= dstdev.capacity &&
884*9781SMoriah.Waterland@Sun.COM partcnt <= nparts) {
885*9781SMoriah.Waterland@Sun.COM totsize += maxpsize;
886*9781SMoriah.Waterland@Sun.COM partcnt++;
887*9781SMoriah.Waterland@Sun.COM }
888*9781SMoriah.Waterland@Sun.COM /* partcnt == 0 means skip to next volume */
889*9781SMoriah.Waterland@Sun.COM if (partcnt)
890*9781SMoriah.Waterland@Sun.COM partcnt--;
891*9781SMoriah.Waterland@Sun.COM (void) snprintf(tmp_entry, ENTRY_MAX,
892*9781SMoriah.Waterland@Sun.COM " %d", partcnt - lastpartcnt);
893*9781SMoriah.Waterland@Sun.COM if (cat_and_count(&hdrbuf, tmp_entry)) {
894*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
895*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
896*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
897*9781SMoriah.Waterland@Sun.COM ecleanup();
898*9781SMoriah.Waterland@Sun.COM return (NULL);
899*9781SMoriah.Waterland@Sun.COM }
900*9781SMoriah.Waterland@Sun.COM ds_volcnt++;
901*9781SMoriah.Waterland@Sun.COM totsize = 0;
902*9781SMoriah.Waterland@Sun.COM lastpartcnt = partcnt;
903*9781SMoriah.Waterland@Sun.COM }
904*9781SMoriah.Waterland@Sun.COM /* first parts/volume number does not count */
905*9781SMoriah.Waterland@Sun.COM ds_volcnt--;
906*9781SMoriah.Waterland@Sun.COM }
907*9781SMoriah.Waterland@Sun.COM
908*9781SMoriah.Waterland@Sun.COM if (cat_and_count(&hdrbuf, "\n")) {
909*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
910*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
911*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
912*9781SMoriah.Waterland@Sun.COM ecleanup();
913*9781SMoriah.Waterland@Sun.COM return (NULL);
914*9781SMoriah.Waterland@Sun.COM }
915*9781SMoriah.Waterland@Sun.COM
916*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
917*9781SMoriah.Waterland@Sun.COM }
918*9781SMoriah.Waterland@Sun.COM
919*9781SMoriah.Waterland@Sun.COM if (cat_and_count(&hdrbuf, HDR_SUFFIX) ||
920*9781SMoriah.Waterland@Sun.COM cat_and_count(&hdrbuf, "\n")) {
921*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
922*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MEM));
923*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
924*9781SMoriah.Waterland@Sun.COM ecleanup();
925*9781SMoriah.Waterland@Sun.COM return (NULL);
926*9781SMoriah.Waterland@Sun.COM }
927*9781SMoriah.Waterland@Sun.COM return (&hdrbuf);
928*9781SMoriah.Waterland@Sun.COM }
929*9781SMoriah.Waterland@Sun.COM
930*9781SMoriah.Waterland@Sun.COM static int
wdsheader(struct dm_buf * hdr,char * src,char * device,char ** pkg,PKCS7 * sig)931*9781SMoriah.Waterland@Sun.COM wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig)
932*9781SMoriah.Waterland@Sun.COM {
933*9781SMoriah.Waterland@Sun.COM FILE *fp;
934*9781SMoriah.Waterland@Sun.COM char path[PATH_MAX], tmp_entry[ENTRY_MAX],
935*9781SMoriah.Waterland@Sun.COM tmp_file[L_tmpnam+1];
936*9781SMoriah.Waterland@Sun.COM char srcpath[PATH_MAX];
937*9781SMoriah.Waterland@Sun.COM int i, n;
938*9781SMoriah.Waterland@Sun.COM int list_fd;
939*9781SMoriah.Waterland@Sun.COM int block_cnt;
940*9781SMoriah.Waterland@Sun.COM int len;
941*9781SMoriah.Waterland@Sun.COM char cwd[MAXPATHLEN + 1];
942*9781SMoriah.Waterland@Sun.COM boolean_t making_sig = B_FALSE;
943*9781SMoriah.Waterland@Sun.COM
944*9781SMoriah.Waterland@Sun.COM making_sig = (sig != NULL) ? B_TRUE : B_FALSE;
945*9781SMoriah.Waterland@Sun.COM
946*9781SMoriah.Waterland@Sun.COM (void) ds_close(0);
947*9781SMoriah.Waterland@Sun.COM if (dstdev.pathname)
948*9781SMoriah.Waterland@Sun.COM ds_fd = creat(device, 0644);
949*9781SMoriah.Waterland@Sun.COM else
950*9781SMoriah.Waterland@Sun.COM ds_fd = open(device, 1);
951*9781SMoriah.Waterland@Sun.COM
952*9781SMoriah.Waterland@Sun.COM if (ds_fd < 0) {
953*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
954*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno);
955*9781SMoriah.Waterland@Sun.COM return (1);
956*9781SMoriah.Waterland@Sun.COM }
957*9781SMoriah.Waterland@Sun.COM
958*9781SMoriah.Waterland@Sun.COM if (ds_ginit(device) < 0) {
959*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
960*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), device, errno);
961*9781SMoriah.Waterland@Sun.COM (void) ds_close(0);
962*9781SMoriah.Waterland@Sun.COM return (1);
963*9781SMoriah.Waterland@Sun.COM }
964*9781SMoriah.Waterland@Sun.COM
965*9781SMoriah.Waterland@Sun.COM /*
966*9781SMoriah.Waterland@Sun.COM * The loop below assures compatibility with tapes that don't
967*9781SMoriah.Waterland@Sun.COM * have a block size (e.g.: Exabyte) by forcing EOR at the end
968*9781SMoriah.Waterland@Sun.COM * of each 512 bytes.
969*9781SMoriah.Waterland@Sun.COM */
970*9781SMoriah.Waterland@Sun.COM for (block_cnt = 0; block_cnt < hdr->allocation;
971*9781SMoriah.Waterland@Sun.COM block_cnt += BLK_SIZE) {
972*9781SMoriah.Waterland@Sun.COM write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE);
973*9781SMoriah.Waterland@Sun.COM }
974*9781SMoriah.Waterland@Sun.COM
975*9781SMoriah.Waterland@Sun.COM /*
976*9781SMoriah.Waterland@Sun.COM * write the first cpio() archive to the datastream
977*9781SMoriah.Waterland@Sun.COM * which should contain the pkginfo & pkgmap files
978*9781SMoriah.Waterland@Sun.COM * for all packages
979*9781SMoriah.Waterland@Sun.COM */
980*9781SMoriah.Waterland@Sun.COM (void) tmpnam(tmp_file); /* temporary file name */
981*9781SMoriah.Waterland@Sun.COM if ((list_fd = open(tmp_file, O_RDWR | O_CREAT)) == -1) {
982*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
983*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTMPFIL));
984*9781SMoriah.Waterland@Sun.COM return (1);
985*9781SMoriah.Waterland@Sun.COM }
986*9781SMoriah.Waterland@Sun.COM
987*9781SMoriah.Waterland@Sun.COM /*
988*9781SMoriah.Waterland@Sun.COM * Create a cpio-compatible list of the requisite files in
989*9781SMoriah.Waterland@Sun.COM * the temporary file.
990*9781SMoriah.Waterland@Sun.COM */
991*9781SMoriah.Waterland@Sun.COM if (!making_sig) {
992*9781SMoriah.Waterland@Sun.COM for (i = 0; pkg[i]; i++) {
993*9781SMoriah.Waterland@Sun.COM register ssize_t entry_size;
994*9781SMoriah.Waterland@Sun.COM
995*9781SMoriah.Waterland@Sun.COM /*
996*9781SMoriah.Waterland@Sun.COM * Copy pkginfo and pkgmap filenames into the
997*9781SMoriah.Waterland@Sun.COM * temporary string allowing for the first line
998*9781SMoriah.Waterland@Sun.COM * as a special case.
999*9781SMoriah.Waterland@Sun.COM */
1000*9781SMoriah.Waterland@Sun.COM entry_size = sprintf(tmp_entry,
1001*9781SMoriah.Waterland@Sun.COM (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
1002*9781SMoriah.Waterland@Sun.COM pkg[i], PKGINFO, pkg[i], PKGMAP);
1003*9781SMoriah.Waterland@Sun.COM
1004*9781SMoriah.Waterland@Sun.COM if (write(list_fd, tmp_entry,
1005*9781SMoriah.Waterland@Sun.COM entry_size) != entry_size) {
1006*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1007*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTMPFIL));
1008*9781SMoriah.Waterland@Sun.COM (void) close(list_fd);
1009*9781SMoriah.Waterland@Sun.COM ecleanup();
1010*9781SMoriah.Waterland@Sun.COM return (1);
1011*9781SMoriah.Waterland@Sun.COM }
1012*9781SMoriah.Waterland@Sun.COM }
1013*9781SMoriah.Waterland@Sun.COM
1014*9781SMoriah.Waterland@Sun.COM } else {
1015*9781SMoriah.Waterland@Sun.COM register ssize_t entry_size;
1016*9781SMoriah.Waterland@Sun.COM
1017*9781SMoriah.Waterland@Sun.COM /*
1018*9781SMoriah.Waterland@Sun.COM * if we're making a signature, we must make a
1019*9781SMoriah.Waterland@Sun.COM * temporary area full of symlinks to the requisite
1020*9781SMoriah.Waterland@Sun.COM * files, plus an extra entry for the signature, so
1021*9781SMoriah.Waterland@Sun.COM * that cpio will put all files and signature in the
1022*9781SMoriah.Waterland@Sun.COM * same archive in a single invocation of cpio.
1023*9781SMoriah.Waterland@Sun.COM */
1024*9781SMoriah.Waterland@Sun.COM tmpsymdir = xstrdup(tmpnam(NULL));
1025*9781SMoriah.Waterland@Sun.COM
1026*9781SMoriah.Waterland@Sun.COM if (mkdir(tmpsymdir, S_IRWXU)) {
1027*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1028*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MKDIR), tmpsymdir);
1029*9781SMoriah.Waterland@Sun.COM return (1);
1030*9781SMoriah.Waterland@Sun.COM }
1031*9781SMoriah.Waterland@Sun.COM
1032*9781SMoriah.Waterland@Sun.COM /* generate the signature */
1033*9781SMoriah.Waterland@Sun.COM if (((len = snprintf(path, PATH_MAX, "%s/%s",
1034*9781SMoriah.Waterland@Sun.COM tmpsymdir, SIGNATURE_FILENAME)) >= PATH_MAX) ||
1035*9781SMoriah.Waterland@Sun.COM len < 0) {
1036*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1037*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTMPFIL), tmpsymdir);
1038*9781SMoriah.Waterland@Sun.COM cleanup();
1039*9781SMoriah.Waterland@Sun.COM return (1);
1040*9781SMoriah.Waterland@Sun.COM }
1041*9781SMoriah.Waterland@Sun.COM
1042*9781SMoriah.Waterland@Sun.COM if ((fp = fopen(path, "w")) == NULL) {
1043*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1044*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTMPFIL), path);
1045*9781SMoriah.Waterland@Sun.COM cleanup();
1046*9781SMoriah.Waterland@Sun.COM return (1);
1047*9781SMoriah.Waterland@Sun.COM }
1048*9781SMoriah.Waterland@Sun.COM PEM_write_PKCS7(fp, sig);
1049*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
1050*9781SMoriah.Waterland@Sun.COM
1051*9781SMoriah.Waterland@Sun.COM for (i = 0; pkg[i]; i++) {
1052*9781SMoriah.Waterland@Sun.COM sprintf(path, "%s/%s", tmpsymdir, pkg[i]);
1053*9781SMoriah.Waterland@Sun.COM if (mkdir(path, 0755)) {
1054*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1055*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MKDIR), path);
1056*9781SMoriah.Waterland@Sun.COM cleanup();
1057*9781SMoriah.Waterland@Sun.COM return (1);
1058*9781SMoriah.Waterland@Sun.COM }
1059*9781SMoriah.Waterland@Sun.COM sprintf(path, "%s/%s/%s", tmpsymdir,
1060*9781SMoriah.Waterland@Sun.COM pkg[i], PKGINFO);
1061*9781SMoriah.Waterland@Sun.COM sprintf(srcpath, "%s/%s/%s", src, pkg[i], PKGINFO);
1062*9781SMoriah.Waterland@Sun.COM if (symlink(srcpath, path) != 0) {
1063*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1064*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SYMLINK), path, srcpath);
1065*9781SMoriah.Waterland@Sun.COM cleanup();
1066*9781SMoriah.Waterland@Sun.COM return (1);
1067*9781SMoriah.Waterland@Sun.COM }
1068*9781SMoriah.Waterland@Sun.COM
1069*9781SMoriah.Waterland@Sun.COM sprintf(path, "%s/%s/%s", tmpsymdir,
1070*9781SMoriah.Waterland@Sun.COM pkg[i], PKGMAP);
1071*9781SMoriah.Waterland@Sun.COM sprintf(srcpath, "%s/%s/%s", src, pkg[i], PKGMAP);
1072*9781SMoriah.Waterland@Sun.COM if (symlink(srcpath, path) != 0) {
1073*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1074*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SYMLINK), path, srcpath);
1075*9781SMoriah.Waterland@Sun.COM cleanup();
1076*9781SMoriah.Waterland@Sun.COM return (1);
1077*9781SMoriah.Waterland@Sun.COM }
1078*9781SMoriah.Waterland@Sun.COM
1079*9781SMoriah.Waterland@Sun.COM /*
1080*9781SMoriah.Waterland@Sun.COM * Copy pkginfo and pkgmap filenames into the
1081*9781SMoriah.Waterland@Sun.COM * temporary string allowing for the first line
1082*9781SMoriah.Waterland@Sun.COM * as a special case.
1083*9781SMoriah.Waterland@Sun.COM */
1084*9781SMoriah.Waterland@Sun.COM entry_size = sprintf(tmp_entry,
1085*9781SMoriah.Waterland@Sun.COM (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
1086*9781SMoriah.Waterland@Sun.COM pkg[i], PKGINFO, pkg[i], PKGMAP);
1087*9781SMoriah.Waterland@Sun.COM
1088*9781SMoriah.Waterland@Sun.COM if (write(list_fd, tmp_entry,
1089*9781SMoriah.Waterland@Sun.COM entry_size) != entry_size) {
1090*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1091*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTMPFIL));
1092*9781SMoriah.Waterland@Sun.COM (void) close(list_fd);
1093*9781SMoriah.Waterland@Sun.COM ecleanup();
1094*9781SMoriah.Waterland@Sun.COM cleanup();
1095*9781SMoriah.Waterland@Sun.COM return (1);
1096*9781SMoriah.Waterland@Sun.COM }
1097*9781SMoriah.Waterland@Sun.COM }
1098*9781SMoriah.Waterland@Sun.COM
1099*9781SMoriah.Waterland@Sun.COM /* add signature to list of files */
1100*9781SMoriah.Waterland@Sun.COM entry_size = sprintf(tmp_entry, "\n%s", SIGNATURE_FILENAME);
1101*9781SMoriah.Waterland@Sun.COM if (write(list_fd, tmp_entry, entry_size) != entry_size) {
1102*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1103*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
1104*9781SMoriah.Waterland@Sun.COM (void) close(list_fd);
1105*9781SMoriah.Waterland@Sun.COM ecleanup();
1106*9781SMoriah.Waterland@Sun.COM cleanup();
1107*9781SMoriah.Waterland@Sun.COM return (1);
1108*9781SMoriah.Waterland@Sun.COM }
1109*9781SMoriah.Waterland@Sun.COM }
1110*9781SMoriah.Waterland@Sun.COM
1111*9781SMoriah.Waterland@Sun.COM (void) lseek(list_fd, 0, SEEK_SET);
1112*9781SMoriah.Waterland@Sun.COM
1113*9781SMoriah.Waterland@Sun.COM if (!making_sig) {
1114*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41
1115*9781SMoriah.Waterland@Sun.COM (void) sprintf(tmp_entry, "%s -ocD -C %d",
1116*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE);
1117*9781SMoriah.Waterland@Sun.COM #else
1118*9781SMoriah.Waterland@Sun.COM (void) sprintf(tmp_entry, "%s -oc -C %d",
1119*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE);
1120*9781SMoriah.Waterland@Sun.COM #endif
1121*9781SMoriah.Waterland@Sun.COM } else {
1122*9781SMoriah.Waterland@Sun.COM /*
1123*9781SMoriah.Waterland@Sun.COM * when making a signature, we must make sure to follow
1124*9781SMoriah.Waterland@Sun.COM * symlinks during the cpio so that we don't archive
1125*9781SMoriah.Waterland@Sun.COM * the links themselves
1126*9781SMoriah.Waterland@Sun.COM */
1127*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41
1128*9781SMoriah.Waterland@Sun.COM (void) sprintf(tmp_entry, "%s -ocDL -C %d",
1129*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE);
1130*9781SMoriah.Waterland@Sun.COM #else
1131*9781SMoriah.Waterland@Sun.COM (void) sprintf(tmp_entry, "%s -ocL -C %d",
1132*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE);
1133*9781SMoriah.Waterland@Sun.COM #endif
1134*9781SMoriah.Waterland@Sun.COM }
1135*9781SMoriah.Waterland@Sun.COM
1136*9781SMoriah.Waterland@Sun.COM if (making_sig) {
1137*9781SMoriah.Waterland@Sun.COM /* save cwd and change to symlink dir for cpio invocation */
1138*9781SMoriah.Waterland@Sun.COM if (getcwd(cwd, MAXPATHLEN + 1) == NULL) {
1139*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(ERR_GETWD));
1140*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1141*9781SMoriah.Waterland@Sun.COM cleanup();
1142*9781SMoriah.Waterland@Sun.COM return (1);
1143*9781SMoriah.Waterland@Sun.COM }
1144*9781SMoriah.Waterland@Sun.COM
1145*9781SMoriah.Waterland@Sun.COM if (chdir(tmpsymdir)) {
1146*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1147*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), tmpsymdir);
1148*9781SMoriah.Waterland@Sun.COM cleanup();
1149*9781SMoriah.Waterland@Sun.COM return (1);
1150*9781SMoriah.Waterland@Sun.COM }
1151*9781SMoriah.Waterland@Sun.COM }
1152*9781SMoriah.Waterland@Sun.COM
1153*9781SMoriah.Waterland@Sun.COM if (n = esystem(tmp_entry, list_fd, ds_fd)) {
1154*9781SMoriah.Waterland@Sun.COM rpterr();
1155*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1156*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n);
1157*9781SMoriah.Waterland@Sun.COM (void) close(list_fd);
1158*9781SMoriah.Waterland@Sun.COM (void) unlink(tmp_file);
1159*9781SMoriah.Waterland@Sun.COM cleanup();
1160*9781SMoriah.Waterland@Sun.COM return (1);
1161*9781SMoriah.Waterland@Sun.COM }
1162*9781SMoriah.Waterland@Sun.COM
1163*9781SMoriah.Waterland@Sun.COM (void) close(list_fd);
1164*9781SMoriah.Waterland@Sun.COM (void) unlink(tmp_file);
1165*9781SMoriah.Waterland@Sun.COM
1166*9781SMoriah.Waterland@Sun.COM if (making_sig) {
1167*9781SMoriah.Waterland@Sun.COM /* change to back to src dir for subsequent operations */
1168*9781SMoriah.Waterland@Sun.COM if (chdir(cwd)) {
1169*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1170*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), cwd);
1171*9781SMoriah.Waterland@Sun.COM cleanup();
1172*9781SMoriah.Waterland@Sun.COM return (1);
1173*9781SMoriah.Waterland@Sun.COM }
1174*9781SMoriah.Waterland@Sun.COM }
1175*9781SMoriah.Waterland@Sun.COM return (0);
1176*9781SMoriah.Waterland@Sun.COM }
1177*9781SMoriah.Waterland@Sun.COM
1178*9781SMoriah.Waterland@Sun.COM static int
ckoverwrite(char * dir,char * inst,int options)1179*9781SMoriah.Waterland@Sun.COM ckoverwrite(char *dir, char *inst, int options)
1180*9781SMoriah.Waterland@Sun.COM {
1181*9781SMoriah.Waterland@Sun.COM char path[PATH_MAX];
1182*9781SMoriah.Waterland@Sun.COM
1183*9781SMoriah.Waterland@Sun.COM (void) sprintf(path, "%s/%s", dir, inst);
1184*9781SMoriah.Waterland@Sun.COM if (access(path, 0) == 0) {
1185*9781SMoriah.Waterland@Sun.COM if (options & PT_OVERWRITE)
1186*9781SMoriah.Waterland@Sun.COM return (rrmdir(path));
1187*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1188*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_EXISTS), path);
1189*9781SMoriah.Waterland@Sun.COM return (1);
1190*9781SMoriah.Waterland@Sun.COM }
1191*9781SMoriah.Waterland@Sun.COM return (0);
1192*9781SMoriah.Waterland@Sun.COM }
1193*9781SMoriah.Waterland@Sun.COM
1194*9781SMoriah.Waterland@Sun.COM static int
pkgxfer(char * srcinst,int options)1195*9781SMoriah.Waterland@Sun.COM pkgxfer(char *srcinst, int options)
1196*9781SMoriah.Waterland@Sun.COM {
1197*9781SMoriah.Waterland@Sun.COM int r;
1198*9781SMoriah.Waterland@Sun.COM struct pkginfo info;
1199*9781SMoriah.Waterland@Sun.COM FILE *fp, *pp;
1200*9781SMoriah.Waterland@Sun.COM char *pt, *src, *dst;
1201*9781SMoriah.Waterland@Sun.COM char dstdir[PATH_MAX],
1202*9781SMoriah.Waterland@Sun.COM temp[PATH_MAX],
1203*9781SMoriah.Waterland@Sun.COM srcdir[PATH_MAX],
1204*9781SMoriah.Waterland@Sun.COM cmd[CMDSIZE],
1205*9781SMoriah.Waterland@Sun.COM pkgname[NON_ABI_NAMELNGTH];
1206*9781SMoriah.Waterland@Sun.COM int i, n, part, nparts, maxpartsize, curpartcnt, iscomp;
1207*9781SMoriah.Waterland@Sun.COM char volnos[128], tmpvol[128];
1208*9781SMoriah.Waterland@Sun.COM struct statvfs64 svfsb;
1209*9781SMoriah.Waterland@Sun.COM longlong_t free_blocks;
1210*9781SMoriah.Waterland@Sun.COM struct stat srcstat;
1211*9781SMoriah.Waterland@Sun.COM
1212*9781SMoriah.Waterland@Sun.COM info.pkginst = NULL; /* required initialization */
1213*9781SMoriah.Waterland@Sun.COM
1214*9781SMoriah.Waterland@Sun.COM /*
1215*9781SMoriah.Waterland@Sun.COM * when this routine is entered, the first part of
1216*9781SMoriah.Waterland@Sun.COM * the package to transfer is already available in
1217*9781SMoriah.Waterland@Sun.COM * the directory indicated by 'src' --- unless the
1218*9781SMoriah.Waterland@Sun.COM * source device is a datstream, in which case only
1219*9781SMoriah.Waterland@Sun.COM * the pkginfo and pkgmap files are available in 'src'
1220*9781SMoriah.Waterland@Sun.COM */
1221*9781SMoriah.Waterland@Sun.COM src = srcdev.dirname;
1222*9781SMoriah.Waterland@Sun.COM dst = dstdev.dirname;
1223*9781SMoriah.Waterland@Sun.COM
1224*9781SMoriah.Waterland@Sun.COM if (!(options & PT_SILENT))
1225*9781SMoriah.Waterland@Sun.COM (void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst);
1226*9781SMoriah.Waterland@Sun.COM (void) strcpy(dstinst, srcinst);
1227*9781SMoriah.Waterland@Sun.COM
1228*9781SMoriah.Waterland@Sun.COM if (!(options & PT_ODTSTREAM)) {
1229*9781SMoriah.Waterland@Sun.COM /* destination is a (possibly mounted) directory */
1230*9781SMoriah.Waterland@Sun.COM (void) sprintf(dstdir, "%s/%s", dst, dstinst);
1231*9781SMoriah.Waterland@Sun.COM
1232*9781SMoriah.Waterland@Sun.COM /*
1233*9781SMoriah.Waterland@Sun.COM * need to check destination directory to assure
1234*9781SMoriah.Waterland@Sun.COM * that we will not be duplicating a package which
1235*9781SMoriah.Waterland@Sun.COM * already resides there (though we are allowed to
1236*9781SMoriah.Waterland@Sun.COM * overwrite the same version)
1237*9781SMoriah.Waterland@Sun.COM */
1238*9781SMoriah.Waterland@Sun.COM pkgdir = src;
1239*9781SMoriah.Waterland@Sun.COM if (fpkginfo(&info, srcinst)) {
1240*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1241*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOEXISTS), srcinst);
1242*9781SMoriah.Waterland@Sun.COM (void) fpkginfo(&info, NULL);
1243*9781SMoriah.Waterland@Sun.COM return (1);
1244*9781SMoriah.Waterland@Sun.COM }
1245*9781SMoriah.Waterland@Sun.COM pkgdir = dst;
1246*9781SMoriah.Waterland@Sun.COM
1247*9781SMoriah.Waterland@Sun.COM (void) strcpy(temp, srcinst);
1248*9781SMoriah.Waterland@Sun.COM if (pt = strchr(temp, '.'))
1249*9781SMoriah.Waterland@Sun.COM *pt = '\0';
1250*9781SMoriah.Waterland@Sun.COM (void) strcat(temp, ".*");
1251*9781SMoriah.Waterland@Sun.COM
1252*9781SMoriah.Waterland@Sun.COM if (pt = fpkginst(temp, info.arch, info.version)) {
1253*9781SMoriah.Waterland@Sun.COM /*
1254*9781SMoriah.Waterland@Sun.COM * the same instance already exists, although
1255*9781SMoriah.Waterland@Sun.COM * its pkgid might be different
1256*9781SMoriah.Waterland@Sun.COM */
1257*9781SMoriah.Waterland@Sun.COM if (options & PT_OVERWRITE) {
1258*9781SMoriah.Waterland@Sun.COM (void) strcpy(dstinst, pt);
1259*9781SMoriah.Waterland@Sun.COM (void) sprintf(dstdir, "%s/%s", dst, dstinst);
1260*9781SMoriah.Waterland@Sun.COM } else {
1261*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1262*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_DUPVERS), srcinst);
1263*9781SMoriah.Waterland@Sun.COM (void) fpkginfo(&info, NULL);
1264*9781SMoriah.Waterland@Sun.COM (void) fpkginst(NULL);
1265*9781SMoriah.Waterland@Sun.COM return (2);
1266*9781SMoriah.Waterland@Sun.COM }
1267*9781SMoriah.Waterland@Sun.COM } else if (options & PT_RENAME) {
1268*9781SMoriah.Waterland@Sun.COM /*
1269*9781SMoriah.Waterland@Sun.COM * find next available instance by appending numbers
1270*9781SMoriah.Waterland@Sun.COM * to the package abbreviation until the instance
1271*9781SMoriah.Waterland@Sun.COM * does not exist in the destination directory
1272*9781SMoriah.Waterland@Sun.COM */
1273*9781SMoriah.Waterland@Sun.COM if (pt = strchr(temp, '.'))
1274*9781SMoriah.Waterland@Sun.COM *pt = '\0';
1275*9781SMoriah.Waterland@Sun.COM for (i = 2; (access(dstdir, 0) == 0); i++) {
1276*9781SMoriah.Waterland@Sun.COM (void) sprintf(dstinst, "%s.%d", temp, i);
1277*9781SMoriah.Waterland@Sun.COM (void) sprintf(dstdir, "%s/%s", dst, dstinst);
1278*9781SMoriah.Waterland@Sun.COM }
1279*9781SMoriah.Waterland@Sun.COM } else if (options & PT_OVERWRITE) {
1280*9781SMoriah.Waterland@Sun.COM /*
1281*9781SMoriah.Waterland@Sun.COM * we're allowed to overwrite, but there seems
1282*9781SMoriah.Waterland@Sun.COM * to be no valid package to overwrite, and we are
1283*9781SMoriah.Waterland@Sun.COM * not allowed to rename the destination, so act
1284*9781SMoriah.Waterland@Sun.COM * as if we weren't given permission to overwrite
1285*9781SMoriah.Waterland@Sun.COM * --- this keeps us from removing a destination
1286*9781SMoriah.Waterland@Sun.COM * instance which is named the same as the source
1287*9781SMoriah.Waterland@Sun.COM * instance, but really reflects a different pkg!
1288*9781SMoriah.Waterland@Sun.COM */
1289*9781SMoriah.Waterland@Sun.COM options &= (~PT_OVERWRITE);
1290*9781SMoriah.Waterland@Sun.COM }
1291*9781SMoriah.Waterland@Sun.COM (void) fpkginfo(&info, NULL);
1292*9781SMoriah.Waterland@Sun.COM (void) fpkginst(NULL);
1293*9781SMoriah.Waterland@Sun.COM
1294*9781SMoriah.Waterland@Sun.COM if (ckoverwrite(dst, dstinst, options))
1295*9781SMoriah.Waterland@Sun.COM return (2);
1296*9781SMoriah.Waterland@Sun.COM
1297*9781SMoriah.Waterland@Sun.COM if (isdir(dstdir) && mkdir(dstdir, 0755)) {
1298*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1299*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MKDIR), dstdir);
1300*9781SMoriah.Waterland@Sun.COM return (1);
1301*9781SMoriah.Waterland@Sun.COM }
1302*9781SMoriah.Waterland@Sun.COM
1303*9781SMoriah.Waterland@Sun.COM (void) sprintf(srcdir, "%s/%s", src, srcinst);
1304*9781SMoriah.Waterland@Sun.COM if (stat(srcdir, &srcstat) != -1) {
1305*9781SMoriah.Waterland@Sun.COM if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) {
1306*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1307*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHMODDIR), dstdir);
1308*9781SMoriah.Waterland@Sun.COM return (1);
1309*9781SMoriah.Waterland@Sun.COM }
1310*9781SMoriah.Waterland@Sun.COM } else {
1311*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1312*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_STATDIR), srcdir);
1313*9781SMoriah.Waterland@Sun.COM return (1);
1314*9781SMoriah.Waterland@Sun.COM }
1315*9781SMoriah.Waterland@Sun.COM }
1316*9781SMoriah.Waterland@Sun.COM
1317*9781SMoriah.Waterland@Sun.COM if (!(options & PT_SILENT) && strcmp(dstinst, srcinst))
1318*9781SMoriah.Waterland@Sun.COM (void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst);
1319*9781SMoriah.Waterland@Sun.COM
1320*9781SMoriah.Waterland@Sun.COM (void) sprintf(srcdir, "%s/%s", src, srcinst);
1321*9781SMoriah.Waterland@Sun.COM if (chdir(srcdir)) {
1322*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1323*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), srcdir);
1324*9781SMoriah.Waterland@Sun.COM return (1);
1325*9781SMoriah.Waterland@Sun.COM }
1326*9781SMoriah.Waterland@Sun.COM
1327*9781SMoriah.Waterland@Sun.COM if (ids_name) { /* unpack the datatstream into a directory */
1328*9781SMoriah.Waterland@Sun.COM /*
1329*9781SMoriah.Waterland@Sun.COM * transfer pkginfo & pkgmap first
1330*9781SMoriah.Waterland@Sun.COM */
1331*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "%s -pudm %s", CPIOPROC, dstdir);
1332*9781SMoriah.Waterland@Sun.COM if ((pp = epopen(cmd, "w")) == NULL) {
1333*9781SMoriah.Waterland@Sun.COM rpterr();
1334*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1335*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_POPEN), cmd, errno);
1336*9781SMoriah.Waterland@Sun.COM return (1);
1337*9781SMoriah.Waterland@Sun.COM }
1338*9781SMoriah.Waterland@Sun.COM (void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP);
1339*9781SMoriah.Waterland@Sun.COM
1340*9781SMoriah.Waterland@Sun.COM sighold(SIGINT);
1341*9781SMoriah.Waterland@Sun.COM sighold(SIGHUP);
1342*9781SMoriah.Waterland@Sun.COM r = epclose(pp);
1343*9781SMoriah.Waterland@Sun.COM sigrelse(SIGINT);
1344*9781SMoriah.Waterland@Sun.COM sigrelse(SIGHUP);
1345*9781SMoriah.Waterland@Sun.COM
1346*9781SMoriah.Waterland@Sun.COM if (r != 0) {
1347*9781SMoriah.Waterland@Sun.COM rpterr();
1348*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1349*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_PCLOSE), cmd, errno);
1350*9781SMoriah.Waterland@Sun.COM return (1);
1351*9781SMoriah.Waterland@Sun.COM }
1352*9781SMoriah.Waterland@Sun.COM
1353*9781SMoriah.Waterland@Sun.COM if (options & PT_INFO_ONLY)
1354*9781SMoriah.Waterland@Sun.COM return (0); /* don't transfer objects */
1355*9781SMoriah.Waterland@Sun.COM
1356*9781SMoriah.Waterland@Sun.COM if (chdir(dstdir)) {
1357*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1358*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), dstdir);
1359*9781SMoriah.Waterland@Sun.COM return (1);
1360*9781SMoriah.Waterland@Sun.COM }
1361*9781SMoriah.Waterland@Sun.COM
1362*9781SMoriah.Waterland@Sun.COM /*
1363*9781SMoriah.Waterland@Sun.COM * for each part of the package, use cpio() to
1364*9781SMoriah.Waterland@Sun.COM * unpack the archive into the destination directory
1365*9781SMoriah.Waterland@Sun.COM */
1366*9781SMoriah.Waterland@Sun.COM nparts = ds_findpkg(srcdev.cdevice, srcinst);
1367*9781SMoriah.Waterland@Sun.COM if (nparts < 0) {
1368*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1369*9781SMoriah.Waterland@Sun.COM return (1);
1370*9781SMoriah.Waterland@Sun.COM }
1371*9781SMoriah.Waterland@Sun.COM for (part = 1; part <= nparts; /* void */) {
1372*9781SMoriah.Waterland@Sun.COM if (ds_getpkg(srcdev.cdevice, part, dstdir)) {
1373*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1374*9781SMoriah.Waterland@Sun.COM return (1);
1375*9781SMoriah.Waterland@Sun.COM }
1376*9781SMoriah.Waterland@Sun.COM part++;
1377*9781SMoriah.Waterland@Sun.COM if (dstdev.mount) {
1378*9781SMoriah.Waterland@Sun.COM (void) chdir("/");
1379*9781SMoriah.Waterland@Sun.COM if (pkgumount(&dstdev))
1380*9781SMoriah.Waterland@Sun.COM return (1);
1381*9781SMoriah.Waterland@Sun.COM if (part <= nparts) {
1382*9781SMoriah.Waterland@Sun.COM if (n = pkgmount(&dstdev, NULL, part+1,
1383*9781SMoriah.Waterland@Sun.COM nparts, 1))
1384*9781SMoriah.Waterland@Sun.COM return (n);
1385*9781SMoriah.Waterland@Sun.COM if (ckoverwrite(dst, dstinst, options))
1386*9781SMoriah.Waterland@Sun.COM return (1);
1387*9781SMoriah.Waterland@Sun.COM if (isdir(dstdir) &&
1388*9781SMoriah.Waterland@Sun.COM mkdir(dstdir, 0755)) {
1389*9781SMoriah.Waterland@Sun.COM progerr(
1390*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_TRANSFER));
1391*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MKDIR),
1392*9781SMoriah.Waterland@Sun.COM dstdir);
1393*9781SMoriah.Waterland@Sun.COM return (1);
1394*9781SMoriah.Waterland@Sun.COM }
1395*9781SMoriah.Waterland@Sun.COM /*
1396*9781SMoriah.Waterland@Sun.COM * since volume is removable, each part
1397*9781SMoriah.Waterland@Sun.COM * must contain a duplicate of the
1398*9781SMoriah.Waterland@Sun.COM * pkginfo file to properly identify the
1399*9781SMoriah.Waterland@Sun.COM * volume
1400*9781SMoriah.Waterland@Sun.COM */
1401*9781SMoriah.Waterland@Sun.COM if (chdir(srcdir)) {
1402*9781SMoriah.Waterland@Sun.COM progerr(
1403*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_TRANSFER));
1404*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR),
1405*9781SMoriah.Waterland@Sun.COM srcdir);
1406*9781SMoriah.Waterland@Sun.COM return (1);
1407*9781SMoriah.Waterland@Sun.COM }
1408*9781SMoriah.Waterland@Sun.COM if ((pp = epopen(cmd, "w")) == NULL) {
1409*9781SMoriah.Waterland@Sun.COM rpterr();
1410*9781SMoriah.Waterland@Sun.COM progerr(
1411*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_TRANSFER));
1412*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_POPEN),
1413*9781SMoriah.Waterland@Sun.COM cmd, errno);
1414*9781SMoriah.Waterland@Sun.COM return (1);
1415*9781SMoriah.Waterland@Sun.COM }
1416*9781SMoriah.Waterland@Sun.COM (void) fprintf(pp, "pkginfo");
1417*9781SMoriah.Waterland@Sun.COM
1418*9781SMoriah.Waterland@Sun.COM sighold(SIGINT);
1419*9781SMoriah.Waterland@Sun.COM sighold(SIGHUP);
1420*9781SMoriah.Waterland@Sun.COM r = epclose(pp);
1421*9781SMoriah.Waterland@Sun.COM sigrelse(SIGINT);
1422*9781SMoriah.Waterland@Sun.COM sigrelse(SIGHUP);
1423*9781SMoriah.Waterland@Sun.COM
1424*9781SMoriah.Waterland@Sun.COM if (r != 0) {
1425*9781SMoriah.Waterland@Sun.COM rpterr();
1426*9781SMoriah.Waterland@Sun.COM progerr(
1427*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_TRANSFER));
1428*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_PCLOSE),
1429*9781SMoriah.Waterland@Sun.COM cmd, errno);
1430*9781SMoriah.Waterland@Sun.COM return (1);
1431*9781SMoriah.Waterland@Sun.COM }
1432*9781SMoriah.Waterland@Sun.COM if (chdir(dstdir)) {
1433*9781SMoriah.Waterland@Sun.COM progerr(
1434*9781SMoriah.Waterland@Sun.COM pkg_gt(ERR_TRANSFER));
1435*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR),
1436*9781SMoriah.Waterland@Sun.COM dstdir);
1437*9781SMoriah.Waterland@Sun.COM return (1);
1438*9781SMoriah.Waterland@Sun.COM }
1439*9781SMoriah.Waterland@Sun.COM }
1440*9781SMoriah.Waterland@Sun.COM }
1441*9781SMoriah.Waterland@Sun.COM }
1442*9781SMoriah.Waterland@Sun.COM return (0);
1443*9781SMoriah.Waterland@Sun.COM }
1444*9781SMoriah.Waterland@Sun.COM
1445*9781SMoriah.Waterland@Sun.COM if ((fp = fopen(PKGMAP, "r")) == NULL) {
1446*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1447*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
1448*9781SMoriah.Waterland@Sun.COM return (1);
1449*9781SMoriah.Waterland@Sun.COM }
1450*9781SMoriah.Waterland@Sun.COM
1451*9781SMoriah.Waterland@Sun.COM nparts = 1;
1452*9781SMoriah.Waterland@Sun.COM if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
1453*9781SMoriah.Waterland@Sun.COM return (1);
1454*9781SMoriah.Waterland@Sun.COM else
1455*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
1456*9781SMoriah.Waterland@Sun.COM
1457*9781SMoriah.Waterland@Sun.COM if (srcdev.mount) {
1458*9781SMoriah.Waterland@Sun.COM if (ckvolseq(srcdir, 1, nparts)) {
1459*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1460*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SEQUENCE));
1461*9781SMoriah.Waterland@Sun.COM return (1);
1462*9781SMoriah.Waterland@Sun.COM }
1463*9781SMoriah.Waterland@Sun.COM }
1464*9781SMoriah.Waterland@Sun.COM
1465*9781SMoriah.Waterland@Sun.COM /* write each part of this package */
1466*9781SMoriah.Waterland@Sun.COM if (options & PT_ODTSTREAM) {
1467*9781SMoriah.Waterland@Sun.COM char line[128];
1468*9781SMoriah.Waterland@Sun.COM (void) mgets(line, 128);
1469*9781SMoriah.Waterland@Sun.COM curpartcnt = -1;
1470*9781SMoriah.Waterland@Sun.COM if (sscanf(line, "%s %d %d %[ 0-9]", &pkgname, &nparts,
1471*9781SMoriah.Waterland@Sun.COM &maxpartsize, volnos) == 4) {
1472*9781SMoriah.Waterland@Sun.COM sscanf(volnos, "%d %[ 0-9]", &curpartcnt, tmpvol);
1473*9781SMoriah.Waterland@Sun.COM strcpy(volnos, tmpvol);
1474*9781SMoriah.Waterland@Sun.COM }
1475*9781SMoriah.Waterland@Sun.COM }
1476*9781SMoriah.Waterland@Sun.COM
1477*9781SMoriah.Waterland@Sun.COM for (part = 1; part <= nparts; /* void */) {
1478*9781SMoriah.Waterland@Sun.COM if (curpartcnt == 0 && (options & PT_ODTSTREAM)) {
1479*9781SMoriah.Waterland@Sun.COM char prompt[128];
1480*9781SMoriah.Waterland@Sun.COM int index;
1481*9781SMoriah.Waterland@Sun.COM ds_volno++;
1482*9781SMoriah.Waterland@Sun.COM (void) ds_close(0);
1483*9781SMoriah.Waterland@Sun.COM (void) sprintf(prompt,
1484*9781SMoriah.Waterland@Sun.COM pkg_gt("Insert %%v %d of %d into %%p"),
1485*9781SMoriah.Waterland@Sun.COM ds_volno, ds_volcnt);
1486*9781SMoriah.Waterland@Sun.COM if (n = getvol(ods_name, NULL, DM_FORMAT, prompt))
1487*9781SMoriah.Waterland@Sun.COM return (n);
1488*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) {
1489*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1490*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
1491*9781SMoriah.Waterland@Sun.COM errno);
1492*9781SMoriah.Waterland@Sun.COM return (1);
1493*9781SMoriah.Waterland@Sun.COM }
1494*9781SMoriah.Waterland@Sun.COM if (ds_ginit(dstdev.cdevice) < 0) {
1495*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1496*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
1497*9781SMoriah.Waterland@Sun.COM errno);
1498*9781SMoriah.Waterland@Sun.COM (void) ds_close(0);
1499*9781SMoriah.Waterland@Sun.COM return (1);
1500*9781SMoriah.Waterland@Sun.COM }
1501*9781SMoriah.Waterland@Sun.COM
1502*9781SMoriah.Waterland@Sun.COM (void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol);
1503*9781SMoriah.Waterland@Sun.COM (void) strcpy(volnos, tmpvol);
1504*9781SMoriah.Waterland@Sun.COM curpartcnt += index;
1505*9781SMoriah.Waterland@Sun.COM }
1506*9781SMoriah.Waterland@Sun.COM
1507*9781SMoriah.Waterland@Sun.COM if (options & PT_INFO_ONLY)
1508*9781SMoriah.Waterland@Sun.COM nparts = 0;
1509*9781SMoriah.Waterland@Sun.COM
1510*9781SMoriah.Waterland@Sun.COM if (part == 1) {
1511*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "find %s %s", PKGINFO, PKGMAP);
1512*9781SMoriah.Waterland@Sun.COM if (nparts && (isdir(INSTALL) == 0)) {
1513*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1514*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, INSTALL);
1515*9781SMoriah.Waterland@Sun.COM }
1516*9781SMoriah.Waterland@Sun.COM } else
1517*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd, "find %s", PKGINFO);
1518*9781SMoriah.Waterland@Sun.COM
1519*9781SMoriah.Waterland@Sun.COM if (nparts > 1) {
1520*9781SMoriah.Waterland@Sun.COM (void) sprintf(temp, "%s.%d", RELOC, part);
1521*9781SMoriah.Waterland@Sun.COM if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
1522*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1523*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, temp);
1524*9781SMoriah.Waterland@Sun.COM }
1525*9781SMoriah.Waterland@Sun.COM (void) sprintf(temp, "%s.%d", ROOT, part);
1526*9781SMoriah.Waterland@Sun.COM if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
1527*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1528*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, temp);
1529*9781SMoriah.Waterland@Sun.COM }
1530*9781SMoriah.Waterland@Sun.COM (void) sprintf(temp, "%s.%d", ARCHIVE, part);
1531*9781SMoriah.Waterland@Sun.COM if (isdir(temp) == 0) {
1532*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1533*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, temp);
1534*9781SMoriah.Waterland@Sun.COM }
1535*9781SMoriah.Waterland@Sun.COM } else if (nparts) {
1536*9781SMoriah.Waterland@Sun.COM for (i = 0; reloc_names[i] != NULL; i++) {
1537*9781SMoriah.Waterland@Sun.COM if (iscpio(reloc_names[i], &iscomp) ||
1538*9781SMoriah.Waterland@Sun.COM isdir(reloc_names[i]) == 0) {
1539*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1540*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, reloc_names[i]);
1541*9781SMoriah.Waterland@Sun.COM }
1542*9781SMoriah.Waterland@Sun.COM }
1543*9781SMoriah.Waterland@Sun.COM for (i = 0; root_names[i] != NULL; i++) {
1544*9781SMoriah.Waterland@Sun.COM if (iscpio(root_names[i], &iscomp) ||
1545*9781SMoriah.Waterland@Sun.COM isdir(root_names[i]) == 0) {
1546*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1547*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, root_names[i]);
1548*9781SMoriah.Waterland@Sun.COM }
1549*9781SMoriah.Waterland@Sun.COM }
1550*9781SMoriah.Waterland@Sun.COM if (isdir(ARCHIVE) == 0) {
1551*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1552*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, ARCHIVE);
1553*9781SMoriah.Waterland@Sun.COM }
1554*9781SMoriah.Waterland@Sun.COM }
1555*9781SMoriah.Waterland@Sun.COM if (options & PT_ODTSTREAM) {
1556*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41
1557*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd+strlen(cmd),
1558*9781SMoriah.Waterland@Sun.COM " -print | %s -ocD -C %d",
1559*9781SMoriah.Waterland@Sun.COM #else
1560*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd+strlen(cmd),
1561*9781SMoriah.Waterland@Sun.COM " -print | %s -oc -C %d",
1562*9781SMoriah.Waterland@Sun.COM #endif
1563*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE);
1564*9781SMoriah.Waterland@Sun.COM } else {
1565*9781SMoriah.Waterland@Sun.COM if (statvfs64(dstdir, &svfsb) == -1) {
1566*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1567*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_STATVFS), dstdir, errno);
1568*9781SMoriah.Waterland@Sun.COM return (1);
1569*9781SMoriah.Waterland@Sun.COM }
1570*9781SMoriah.Waterland@Sun.COM
1571*9781SMoriah.Waterland@Sun.COM free_blocks = (((long)svfsb.f_frsize > 0) ?
1572*9781SMoriah.Waterland@Sun.COM howmany(svfsb.f_frsize, DEV_BSIZE) :
1573*9781SMoriah.Waterland@Sun.COM howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;
1574*9781SMoriah.Waterland@Sun.COM
1575*9781SMoriah.Waterland@Sun.COM if ((has_comp_size ? compressedsize : maxpartsize) >
1576*9781SMoriah.Waterland@Sun.COM free_blocks) {
1577*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1578*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOSPACE));
1579*9781SMoriah.Waterland@Sun.COM return (1);
1580*9781SMoriah.Waterland@Sun.COM }
1581*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd+strlen(cmd), " -print | %s -pdum %s",
1582*9781SMoriah.Waterland@Sun.COM CPIOPROC, dstdir);
1583*9781SMoriah.Waterland@Sun.COM }
1584*9781SMoriah.Waterland@Sun.COM
1585*9781SMoriah.Waterland@Sun.COM n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1);
1586*9781SMoriah.Waterland@Sun.COM if (n) {
1587*9781SMoriah.Waterland@Sun.COM rpterr();
1588*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1589*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
1590*9781SMoriah.Waterland@Sun.COM return (1);
1591*9781SMoriah.Waterland@Sun.COM }
1592*9781SMoriah.Waterland@Sun.COM
1593*9781SMoriah.Waterland@Sun.COM part++;
1594*9781SMoriah.Waterland@Sun.COM if (srcdev.mount && (nparts > 1)) {
1595*9781SMoriah.Waterland@Sun.COM /* unmount current source volume */
1596*9781SMoriah.Waterland@Sun.COM (void) chdir("/");
1597*9781SMoriah.Waterland@Sun.COM if (pkgumount(&srcdev))
1598*9781SMoriah.Waterland@Sun.COM return (1);
1599*9781SMoriah.Waterland@Sun.COM /* loop until volume is mounted successfully */
1600*9781SMoriah.Waterland@Sun.COM while (part <= nparts) {
1601*9781SMoriah.Waterland@Sun.COM /* read only */
1602*9781SMoriah.Waterland@Sun.COM n = pkgmount(&srcdev, NULL, part, nparts, 1);
1603*9781SMoriah.Waterland@Sun.COM if (n)
1604*9781SMoriah.Waterland@Sun.COM return (n);
1605*9781SMoriah.Waterland@Sun.COM if (chdir(srcdir)) {
1606*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1607*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CORRUPT), srcdir);
1608*9781SMoriah.Waterland@Sun.COM (void) chdir("/");
1609*9781SMoriah.Waterland@Sun.COM pkgumount(&srcdev);
1610*9781SMoriah.Waterland@Sun.COM continue;
1611*9781SMoriah.Waterland@Sun.COM }
1612*9781SMoriah.Waterland@Sun.COM if (ckvolseq(srcdir, part, nparts)) {
1613*9781SMoriah.Waterland@Sun.COM (void) chdir("/");
1614*9781SMoriah.Waterland@Sun.COM pkgumount(&srcdev);
1615*9781SMoriah.Waterland@Sun.COM continue;
1616*9781SMoriah.Waterland@Sun.COM }
1617*9781SMoriah.Waterland@Sun.COM break;
1618*9781SMoriah.Waterland@Sun.COM }
1619*9781SMoriah.Waterland@Sun.COM }
1620*9781SMoriah.Waterland@Sun.COM if (!(options & PT_ODTSTREAM) && dstdev.mount) {
1621*9781SMoriah.Waterland@Sun.COM /* unmount current volume */
1622*9781SMoriah.Waterland@Sun.COM if (pkgumount(&dstdev))
1623*9781SMoriah.Waterland@Sun.COM return (1);
1624*9781SMoriah.Waterland@Sun.COM /* loop until next volume is mounted successfully */
1625*9781SMoriah.Waterland@Sun.COM while (part <= nparts) {
1626*9781SMoriah.Waterland@Sun.COM /* writable */
1627*9781SMoriah.Waterland@Sun.COM n = pkgmount(&dstdev, NULL, part, nparts, 1);
1628*9781SMoriah.Waterland@Sun.COM if (n)
1629*9781SMoriah.Waterland@Sun.COM return (n);
1630*9781SMoriah.Waterland@Sun.COM if (ckoverwrite(dst, dstinst, options))
1631*9781SMoriah.Waterland@Sun.COM continue;
1632*9781SMoriah.Waterland@Sun.COM if (isdir(dstdir) && mkdir(dstdir, 0755)) {
1633*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1634*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_MKDIR), dstdir);
1635*9781SMoriah.Waterland@Sun.COM continue;
1636*9781SMoriah.Waterland@Sun.COM }
1637*9781SMoriah.Waterland@Sun.COM break;
1638*9781SMoriah.Waterland@Sun.COM }
1639*9781SMoriah.Waterland@Sun.COM }
1640*9781SMoriah.Waterland@Sun.COM
1641*9781SMoriah.Waterland@Sun.COM if ((options & PT_ODTSTREAM) && part <= nparts) {
1642*9781SMoriah.Waterland@Sun.COM if (curpartcnt >= 0 && part > curpartcnt) {
1643*9781SMoriah.Waterland@Sun.COM char prompt[128];
1644*9781SMoriah.Waterland@Sun.COM int index;
1645*9781SMoriah.Waterland@Sun.COM ds_volno++;
1646*9781SMoriah.Waterland@Sun.COM if (ds_close(0))
1647*9781SMoriah.Waterland@Sun.COM return (1);
1648*9781SMoriah.Waterland@Sun.COM (void) sprintf(prompt,
1649*9781SMoriah.Waterland@Sun.COM pkg_gt("Insert %%v %d of %d into %%p"),
1650*9781SMoriah.Waterland@Sun.COM ds_volno, ds_volcnt);
1651*9781SMoriah.Waterland@Sun.COM if (n = getvol(ods_name, NULL, DM_FORMAT,
1652*9781SMoriah.Waterland@Sun.COM prompt))
1653*9781SMoriah.Waterland@Sun.COM return (n);
1654*9781SMoriah.Waterland@Sun.COM if ((ds_fd = open(dstdev.cdevice, 1)) < 0) {
1655*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1656*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN),
1657*9781SMoriah.Waterland@Sun.COM dstdev.cdevice, errno);
1658*9781SMoriah.Waterland@Sun.COM return (1);
1659*9781SMoriah.Waterland@Sun.COM }
1660*9781SMoriah.Waterland@Sun.COM if (ds_ginit(dstdev.cdevice) < 0) {
1661*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1662*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_OPEN),
1663*9781SMoriah.Waterland@Sun.COM dstdev.cdevice, errno);
1664*9781SMoriah.Waterland@Sun.COM (void) ds_close(0);
1665*9781SMoriah.Waterland@Sun.COM return (1);
1666*9781SMoriah.Waterland@Sun.COM }
1667*9781SMoriah.Waterland@Sun.COM
1668*9781SMoriah.Waterland@Sun.COM (void) sscanf(volnos, "%d %[ 0-9]", &index,
1669*9781SMoriah.Waterland@Sun.COM tmpvol);
1670*9781SMoriah.Waterland@Sun.COM (void) strcpy(volnos, tmpvol);
1671*9781SMoriah.Waterland@Sun.COM curpartcnt += index;
1672*9781SMoriah.Waterland@Sun.COM }
1673*9781SMoriah.Waterland@Sun.COM }
1674*9781SMoriah.Waterland@Sun.COM
1675*9781SMoriah.Waterland@Sun.COM }
1676*9781SMoriah.Waterland@Sun.COM return (0);
1677*9781SMoriah.Waterland@Sun.COM }
1678*9781SMoriah.Waterland@Sun.COM
1679*9781SMoriah.Waterland@Sun.COM /*
1680*9781SMoriah.Waterland@Sun.COM * Name: pkgdump
1681*9781SMoriah.Waterland@Sun.COM * Description: Dump a cpio archive of a package's contents to a BIO.
1682*9781SMoriah.Waterland@Sun.COM *
1683*9781SMoriah.Waterland@Sun.COM * Arguments: srcinst - Name of package, which resides on the
1684*9781SMoriah.Waterland@Sun.COM * device pointed to by the static 'srcdev' variable,
1685*9781SMoriah.Waterland@Sun.COM * to dump.
1686*9781SMoriah.Waterland@Sun.COM * bio - BIO object to dump data to
1687*9781SMoriah.Waterland@Sun.COM *
1688*9781SMoriah.Waterland@Sun.COM * Returns : 0 - success
1689*9781SMoriah.Waterland@Sun.COM * nonzero - failure. errors printed to screen.
1690*9781SMoriah.Waterland@Sun.COM */
1691*9781SMoriah.Waterland@Sun.COM static int
pkgdump(char * srcinst,BIO * bio)1692*9781SMoriah.Waterland@Sun.COM pkgdump(char *srcinst, BIO *bio)
1693*9781SMoriah.Waterland@Sun.COM {
1694*9781SMoriah.Waterland@Sun.COM FILE *fp;
1695*9781SMoriah.Waterland@Sun.COM char *src;
1696*9781SMoriah.Waterland@Sun.COM char temp[MAXPATHLEN],
1697*9781SMoriah.Waterland@Sun.COM srcdir[MAXPATHLEN],
1698*9781SMoriah.Waterland@Sun.COM cmd[CMDSIZE];
1699*9781SMoriah.Waterland@Sun.COM int i, n, part, nparts, maxpartsize, iscomp;
1700*9781SMoriah.Waterland@Sun.COM
1701*9781SMoriah.Waterland@Sun.COM /*
1702*9781SMoriah.Waterland@Sun.COM * when this routine is entered, the entire package
1703*9781SMoriah.Waterland@Sun.COM * is already available at 'src' - including the
1704*9781SMoriah.Waterland@Sun.COM * pkginfo/pkgmap files and the objects as well.
1705*9781SMoriah.Waterland@Sun.COM */
1706*9781SMoriah.Waterland@Sun.COM
1707*9781SMoriah.Waterland@Sun.COM /* read the pkgmap to get it's size information */
1708*9781SMoriah.Waterland@Sun.COM if ((fp = fopen(PKGMAP, "r")) == NULL) {
1709*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1710*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
1711*9781SMoriah.Waterland@Sun.COM return (1);
1712*9781SMoriah.Waterland@Sun.COM }
1713*9781SMoriah.Waterland@Sun.COM
1714*9781SMoriah.Waterland@Sun.COM nparts = 1;
1715*9781SMoriah.Waterland@Sun.COM if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
1716*9781SMoriah.Waterland@Sun.COM return (1);
1717*9781SMoriah.Waterland@Sun.COM else
1718*9781SMoriah.Waterland@Sun.COM (void) fclose(fp);
1719*9781SMoriah.Waterland@Sun.COM
1720*9781SMoriah.Waterland@Sun.COM /* make sure the first volume is available */
1721*9781SMoriah.Waterland@Sun.COM if (srcdev.mount) {
1722*9781SMoriah.Waterland@Sun.COM src = srcdev.dirname;
1723*9781SMoriah.Waterland@Sun.COM (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, srcinst);
1724*9781SMoriah.Waterland@Sun.COM if (ckvolseq(srcdir, 1, nparts)) {
1725*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1726*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_SEQUENCE));
1727*9781SMoriah.Waterland@Sun.COM return (1);
1728*9781SMoriah.Waterland@Sun.COM }
1729*9781SMoriah.Waterland@Sun.COM }
1730*9781SMoriah.Waterland@Sun.COM
1731*9781SMoriah.Waterland@Sun.COM /*
1732*9781SMoriah.Waterland@Sun.COM * form cpio command that will output the contents of all of
1733*9781SMoriah.Waterland@Sun.COM * this package's parts
1734*9781SMoriah.Waterland@Sun.COM */
1735*9781SMoriah.Waterland@Sun.COM for (part = 1; part <= nparts; /* void */) {
1736*9781SMoriah.Waterland@Sun.COM
1737*9781SMoriah.Waterland@Sun.COM if (part == 1) {
1738*9781SMoriah.Waterland@Sun.COM (void) snprintf(cmd, CMDSIZE, "find %s %s",
1739*9781SMoriah.Waterland@Sun.COM PKGINFO, PKGMAP);
1740*9781SMoriah.Waterland@Sun.COM if (nparts && (isdir(INSTALL) == 0)) {
1741*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, " ");
1742*9781SMoriah.Waterland@Sun.COM (void) strcat(cmd, INSTALL);
1743*9781SMoriah.Waterland@Sun.COM }
1744*9781SMoriah.Waterland@Sun.COM } else
1745*9781SMoriah.Waterland@Sun.COM (void) snprintf(cmd, CMDSIZE, "find %s", PKGINFO);
1746*9781SMoriah.Waterland@Sun.COM
1747*9781SMoriah.Waterland@Sun.COM if (nparts > 1) {
1748*9781SMoriah.Waterland@Sun.COM (void) snprintf(temp, MAXPATHLEN, "%s.%d", RELOC, part);
1749*9781SMoriah.Waterland@Sun.COM if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
1750*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, " ", CMDSIZE);
1751*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, temp, CMDSIZE);
1752*9781SMoriah.Waterland@Sun.COM }
1753*9781SMoriah.Waterland@Sun.COM (void) snprintf(temp, MAXPATHLEN, "%s.%d", ROOT, part);
1754*9781SMoriah.Waterland@Sun.COM if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
1755*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, " ", CMDSIZE);
1756*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, temp, CMDSIZE);
1757*9781SMoriah.Waterland@Sun.COM }
1758*9781SMoriah.Waterland@Sun.COM (void) snprintf(temp, MAXPATHLEN, "%s.%d",
1759*9781SMoriah.Waterland@Sun.COM ARCHIVE, part);
1760*9781SMoriah.Waterland@Sun.COM if (isdir(temp) == 0) {
1761*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, " ", CMDSIZE);
1762*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, temp, CMDSIZE);
1763*9781SMoriah.Waterland@Sun.COM }
1764*9781SMoriah.Waterland@Sun.COM } else if (nparts) {
1765*9781SMoriah.Waterland@Sun.COM for (i = 0; reloc_names[i] != NULL; i++) {
1766*9781SMoriah.Waterland@Sun.COM if (iscpio(reloc_names[i], &iscomp) ||
1767*9781SMoriah.Waterland@Sun.COM isdir(reloc_names[i]) == 0) {
1768*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, " ", CMDSIZE);
1769*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, reloc_names[i],
1770*9781SMoriah.Waterland@Sun.COM CMDSIZE);
1771*9781SMoriah.Waterland@Sun.COM }
1772*9781SMoriah.Waterland@Sun.COM }
1773*9781SMoriah.Waterland@Sun.COM for (i = 0; root_names[i] != NULL; i++) {
1774*9781SMoriah.Waterland@Sun.COM if (iscpio(root_names[i], &iscomp) ||
1775*9781SMoriah.Waterland@Sun.COM isdir(root_names[i]) == 0) {
1776*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, " ", CMDSIZE);
1777*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, root_names[i],
1778*9781SMoriah.Waterland@Sun.COM CMDSIZE);
1779*9781SMoriah.Waterland@Sun.COM }
1780*9781SMoriah.Waterland@Sun.COM }
1781*9781SMoriah.Waterland@Sun.COM if (isdir(ARCHIVE) == 0) {
1782*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, " ", CMDSIZE);
1783*9781SMoriah.Waterland@Sun.COM (void) strlcat(cmd, ARCHIVE, CMDSIZE);
1784*9781SMoriah.Waterland@Sun.COM }
1785*9781SMoriah.Waterland@Sun.COM }
1786*9781SMoriah.Waterland@Sun.COM
1787*9781SMoriah.Waterland@Sun.COM #ifndef SUNOS41
1788*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd+strlen(cmd),
1789*9781SMoriah.Waterland@Sun.COM " -print | %s -ocD -C %d",
1790*9781SMoriah.Waterland@Sun.COM #else
1791*9781SMoriah.Waterland@Sun.COM (void) sprintf(cmd+strlen(cmd),
1792*9781SMoriah.Waterland@Sun.COM " -print | %s -oc -C %d",
1793*9781SMoriah.Waterland@Sun.COM #endif
1794*9781SMoriah.Waterland@Sun.COM CPIOPROC, (int)BLK_SIZE);
1795*9781SMoriah.Waterland@Sun.COM /*
1796*9781SMoriah.Waterland@Sun.COM * execute the command, dumping all standard output
1797*9781SMoriah.Waterland@Sun.COM * to the BIO.
1798*9781SMoriah.Waterland@Sun.COM */
1799*9781SMoriah.Waterland@Sun.COM n = BIO_dump_cmd(cmd, bio);
1800*9781SMoriah.Waterland@Sun.COM if (n != 0) {
1801*9781SMoriah.Waterland@Sun.COM rpterr();
1802*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1803*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
1804*9781SMoriah.Waterland@Sun.COM return (1);
1805*9781SMoriah.Waterland@Sun.COM }
1806*9781SMoriah.Waterland@Sun.COM
1807*9781SMoriah.Waterland@Sun.COM part++;
1808*9781SMoriah.Waterland@Sun.COM }
1809*9781SMoriah.Waterland@Sun.COM return (0);
1810*9781SMoriah.Waterland@Sun.COM }
1811*9781SMoriah.Waterland@Sun.COM
1812*9781SMoriah.Waterland@Sun.COM static void
sigtrap(int signo)1813*9781SMoriah.Waterland@Sun.COM sigtrap(int signo)
1814*9781SMoriah.Waterland@Sun.COM {
1815*9781SMoriah.Waterland@Sun.COM signal_received++;
1816*9781SMoriah.Waterland@Sun.COM }
1817*9781SMoriah.Waterland@Sun.COM
1818*9781SMoriah.Waterland@Sun.COM static void
cleanup(void)1819*9781SMoriah.Waterland@Sun.COM cleanup(void)
1820*9781SMoriah.Waterland@Sun.COM {
1821*9781SMoriah.Waterland@Sun.COM chdir("/");
1822*9781SMoriah.Waterland@Sun.COM if (tmpdir) {
1823*9781SMoriah.Waterland@Sun.COM rrmdir(tmpdir);
1824*9781SMoriah.Waterland@Sun.COM free(tmpdir);
1825*9781SMoriah.Waterland@Sun.COM tmpdir = NULL;
1826*9781SMoriah.Waterland@Sun.COM }
1827*9781SMoriah.Waterland@Sun.COM
1828*9781SMoriah.Waterland@Sun.COM if (tmppath) {
1829*9781SMoriah.Waterland@Sun.COM /* remove any previous tmppath stuff */
1830*9781SMoriah.Waterland@Sun.COM rrmdir(tmppath);
1831*9781SMoriah.Waterland@Sun.COM free(tmppath);
1832*9781SMoriah.Waterland@Sun.COM tmppath = NULL;
1833*9781SMoriah.Waterland@Sun.COM }
1834*9781SMoriah.Waterland@Sun.COM
1835*9781SMoriah.Waterland@Sun.COM if (tmpsymdir) {
1836*9781SMoriah.Waterland@Sun.COM /* remove temp symbolic links made for signed pkg */
1837*9781SMoriah.Waterland@Sun.COM rrmdir(tmpsymdir);
1838*9781SMoriah.Waterland@Sun.COM free(tmpsymdir);
1839*9781SMoriah.Waterland@Sun.COM tmpsymdir = NULL;
1840*9781SMoriah.Waterland@Sun.COM }
1841*9781SMoriah.Waterland@Sun.COM
1842*9781SMoriah.Waterland@Sun.COM if (srcdev.mount && !ids_name)
1843*9781SMoriah.Waterland@Sun.COM pkgumount(&srcdev);
1844*9781SMoriah.Waterland@Sun.COM if (dstdev.mount && !ods_name)
1845*9781SMoriah.Waterland@Sun.COM pkgumount(&dstdev);
1846*9781SMoriah.Waterland@Sun.COM (void) ds_close(1);
1847*9781SMoriah.Waterland@Sun.COM }
1848*9781SMoriah.Waterland@Sun.COM
1849*9781SMoriah.Waterland@Sun.COM /*
1850*9781SMoriah.Waterland@Sun.COM * Name: dump_hdr_and_pkgs
1851*9781SMoriah.Waterland@Sun.COM * Description: Dumps datastream header and each package's contents
1852*9781SMoriah.Waterland@Sun.COM * to the supplied BIO
1853*9781SMoriah.Waterland@Sun.COM *
1854*9781SMoriah.Waterland@Sun.COM * Arguments: bio - BIO object to dump data to
1855*9781SMoriah.Waterland@Sun.COM * hdr - Header for the datastream being dumped
1856*9781SMoriah.Waterland@Sun.COM * pkglist - NULL-terminated list of packages
1857*9781SMoriah.Waterland@Sun.COM * to dump. The location of the packages are stored
1858*9781SMoriah.Waterland@Sun.COM * in the static 'srcdev' variable.
1859*9781SMoriah.Waterland@Sun.COM *
1860*9781SMoriah.Waterland@Sun.COM * Returns : 0 - success
1861*9781SMoriah.Waterland@Sun.COM * nonzero - failure. errors printed to screen.
1862*9781SMoriah.Waterland@Sun.COM */
1863*9781SMoriah.Waterland@Sun.COM static int
dump_hdr_and_pkgs(BIO * bio,struct dm_buf * hdr,char ** pkglist)1864*9781SMoriah.Waterland@Sun.COM dump_hdr_and_pkgs(BIO *bio, struct dm_buf *hdr, char **pkglist)
1865*9781SMoriah.Waterland@Sun.COM {
1866*9781SMoriah.Waterland@Sun.COM int block_cnt, i;
1867*9781SMoriah.Waterland@Sun.COM char srcdir[MAXPATHLEN];
1868*9781SMoriah.Waterland@Sun.COM char cwd[MAXPATHLEN + 1];
1869*9781SMoriah.Waterland@Sun.COM char *src;
1870*9781SMoriah.Waterland@Sun.COM
1871*9781SMoriah.Waterland@Sun.COM /* write out the header to the signature stream */
1872*9781SMoriah.Waterland@Sun.COM for (block_cnt = 0; block_cnt < hdr->allocation;
1873*9781SMoriah.Waterland@Sun.COM block_cnt += BLK_SIZE) {
1874*9781SMoriah.Waterland@Sun.COM BIO_write(bio, (hdr->text_buffer + block_cnt), BLK_SIZE);
1875*9781SMoriah.Waterland@Sun.COM }
1876*9781SMoriah.Waterland@Sun.COM
1877*9781SMoriah.Waterland@Sun.COM /* save current directory */
1878*9781SMoriah.Waterland@Sun.COM if (getcwd(cwd, MAXPATHLEN + 1) == NULL) {
1879*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(ERR_GETWD));
1880*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1881*9781SMoriah.Waterland@Sun.COM return (1);
1882*9781SMoriah.Waterland@Sun.COM }
1883*9781SMoriah.Waterland@Sun.COM
1884*9781SMoriah.Waterland@Sun.COM /* now write out each package's contents */
1885*9781SMoriah.Waterland@Sun.COM for (i = 0; pkglist[i]; i++) {
1886*9781SMoriah.Waterland@Sun.COM /*
1887*9781SMoriah.Waterland@Sun.COM * change to the source dir, so we can find and dump
1888*9781SMoriah.Waterland@Sun.COM * the package(s) bits into the BIO
1889*9781SMoriah.Waterland@Sun.COM *
1890*9781SMoriah.Waterland@Sun.COM */
1891*9781SMoriah.Waterland@Sun.COM src = srcdev.dirname;
1892*9781SMoriah.Waterland@Sun.COM
1893*9781SMoriah.Waterland@Sun.COM /* change to the package source directory */
1894*9781SMoriah.Waterland@Sun.COM (void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, pkglist[i]);
1895*9781SMoriah.Waterland@Sun.COM if (chdir(srcdir)) {
1896*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1897*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), srcdir);
1898*9781SMoriah.Waterland@Sun.COM return (1);
1899*9781SMoriah.Waterland@Sun.COM }
1900*9781SMoriah.Waterland@Sun.COM
1901*9781SMoriah.Waterland@Sun.COM if (pkgdump(pkglist[i], bio)) {
1902*9781SMoriah.Waterland@Sun.COM pkglist[i] = NULL;
1903*9781SMoriah.Waterland@Sun.COM return (1);
1904*9781SMoriah.Waterland@Sun.COM }
1905*9781SMoriah.Waterland@Sun.COM }
1906*9781SMoriah.Waterland@Sun.COM
1907*9781SMoriah.Waterland@Sun.COM /* change back to directory we were in upon entering this routine */
1908*9781SMoriah.Waterland@Sun.COM if (chdir(cwd)) {
1909*9781SMoriah.Waterland@Sun.COM progerr(pkg_gt(ERR_TRANSFER));
1910*9781SMoriah.Waterland@Sun.COM logerr(pkg_gt(MSG_CHDIR), cwd);
1911*9781SMoriah.Waterland@Sun.COM return (1);
1912*9781SMoriah.Waterland@Sun.COM }
1913*9781SMoriah.Waterland@Sun.COM
1914*9781SMoriah.Waterland@Sun.COM return (0);
1915*9781SMoriah.Waterland@Sun.COM }
1916*9781SMoriah.Waterland@Sun.COM
1917*9781SMoriah.Waterland@Sun.COM /*
1918*9781SMoriah.Waterland@Sun.COM * Name: BIO_dump_cmd
1919*9781SMoriah.Waterland@Sun.COM * Description: Dump the output of invoking a command
1920*9781SMoriah.Waterland@Sun.COM * to a BIO.
1921*9781SMoriah.Waterland@Sun.COM *
1922*9781SMoriah.Waterland@Sun.COM * Arguments: cmd - Command to invoke
1923*9781SMoriah.Waterland@Sun.COM * bio - BIO to dump output of command to
1924*9781SMoriah.Waterland@Sun.COM * only 'stdout' is dumped.
1925*9781SMoriah.Waterland@Sun.COM * Returns : 0 - success
1926*9781SMoriah.Waterland@Sun.COM * nonzero - failure. errors printed to screen.
1927*9781SMoriah.Waterland@Sun.COM */
1928*9781SMoriah.Waterland@Sun.COM int
BIO_dump_cmd(char * cmd,BIO * bio)1929*9781SMoriah.Waterland@Sun.COM BIO_dump_cmd(char *cmd, BIO *bio)
1930*9781SMoriah.Waterland@Sun.COM {
1931*9781SMoriah.Waterland@Sun.COM char buf[BLK_SIZE];
1932*9781SMoriah.Waterland@Sun.COM FILE *fp;
1933*9781SMoriah.Waterland@Sun.COM int rc;
1934*9781SMoriah.Waterland@Sun.COM
1935*9781SMoriah.Waterland@Sun.COM /* start up the process */
1936*9781SMoriah.Waterland@Sun.COM if ((fp = epopen(cmd, "r")) == NULL) {
1937*9781SMoriah.Waterland@Sun.COM rpterr();
1938*9781SMoriah.Waterland@Sun.COM return (1);
1939*9781SMoriah.Waterland@Sun.COM }
1940*9781SMoriah.Waterland@Sun.COM
1941*9781SMoriah.Waterland@Sun.COM /* read output in chunks, transfer to BIO */
1942*9781SMoriah.Waterland@Sun.COM while (fread(buf, BLK_SIZE, 1, fp) == 1) {
1943*9781SMoriah.Waterland@Sun.COM if (BIO_write(bio, buf, BLK_SIZE) != BLK_SIZE) {
1944*9781SMoriah.Waterland@Sun.COM sighold(SIGINT);
1945*9781SMoriah.Waterland@Sun.COM sighold(SIGHUP);
1946*9781SMoriah.Waterland@Sun.COM (void) epclose(fp);
1947*9781SMoriah.Waterland@Sun.COM sigrelse(SIGINT);
1948*9781SMoriah.Waterland@Sun.COM sigrelse(SIGHUP);
1949*9781SMoriah.Waterland@Sun.COM rpterr();
1950*9781SMoriah.Waterland@Sun.COM return (1);
1951*9781SMoriah.Waterland@Sun.COM }
1952*9781SMoriah.Waterland@Sun.COM }
1953*9781SMoriah.Waterland@Sun.COM
1954*9781SMoriah.Waterland@Sun.COM /* done with stream, make sure no errors were encountered */
1955*9781SMoriah.Waterland@Sun.COM if (ferror(fp)) {
1956*9781SMoriah.Waterland@Sun.COM (void) epclose(fp);
1957*9781SMoriah.Waterland@Sun.COM rpterr();
1958*9781SMoriah.Waterland@Sun.COM return (1);
1959*9781SMoriah.Waterland@Sun.COM }
1960*9781SMoriah.Waterland@Sun.COM
1961*9781SMoriah.Waterland@Sun.COM /* done, close stream, report any errors */
1962*9781SMoriah.Waterland@Sun.COM sighold(SIGINT);
1963*9781SMoriah.Waterland@Sun.COM sighold(SIGHUP);
1964*9781SMoriah.Waterland@Sun.COM rc = epclose(fp);
1965*9781SMoriah.Waterland@Sun.COM sigrelse(SIGINT);
1966*9781SMoriah.Waterland@Sun.COM sigrelse(SIGHUP);
1967*9781SMoriah.Waterland@Sun.COM if (rc != 0) {
1968*9781SMoriah.Waterland@Sun.COM rpterr();
1969*9781SMoriah.Waterland@Sun.COM return (1);
1970*9781SMoriah.Waterland@Sun.COM }
1971*9781SMoriah.Waterland@Sun.COM
1972*9781SMoriah.Waterland@Sun.COM return (rc);
1973*9781SMoriah.Waterland@Sun.COM }
1974