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