ar_io.c revision 1.24 1 /* $NetBSD: ar_io.c,v 1.24 2002/10/12 18:49:28 thorpej Exp $ */
2
3 /*-
4 * Copyright (c) 1992 Keith Muller.
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Keith Muller of the University of California, San Diego.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 */
39
40 #include <sys/cdefs.h>
41 #if defined(__RCSID) && !defined(lint)
42 #if 0
43 static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94";
44 #else
45 __RCSID("$NetBSD: ar_io.c,v 1.24 2002/10/12 18:49:28 thorpej Exp $");
46 #endif
47 #endif /* not lint */
48
49 #include <sys/types.h>
50 #include <sys/time.h>
51 #include <sys/stat.h>
52 #include <sys/ioctl.h>
53 #include <sys/mtio.h>
54 #include <sys/param.h>
55 #include <sys/wait.h>
56 #include <signal.h>
57 #include <string.h>
58 #include <fcntl.h>
59 #include <unistd.h>
60 #include <stdio.h>
61 #include <ctype.h>
62 #include <errno.h>
63 #include <stdlib.h>
64 #define __RMTLIB_PRIVATE
65 #include <rmt.h>
66 #include "pax.h"
67 #include "options.h"
68 #include "extern.h"
69
70 /*
71 * Routines which deal directly with the archive I/O device/file.
72 */
73
74 #define DMOD 0666 /* default mode of created archives */
75 #define EXT_MODE O_RDONLY /* open mode for list/extract */
76 #define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */
77 #define APP_MODE O_RDWR /* mode for append */
78 #define STDO "<STDOUT>" /* pseudo name for stdout */
79 #define STDN "<STDIN>" /* pseudo name for stdin */
80 static int arfd = -1; /* archive file descriptor */
81 static int artyp = ISREG; /* archive type: file/FIFO/tape */
82 static int arvol = 1; /* archive volume number */
83 static int lstrval = -1; /* return value from last i/o */
84 static int io_ok; /* i/o worked on volume after resync */
85 static int did_io; /* did i/o ever occur on volume? */
86 static int done; /* set via tty termination */
87 static struct stat arsb; /* stat of archive device at open */
88 static int invld_rec; /* tape has out of spec record size */
89 static int wr_trail = 1; /* trailer was rewritten in append */
90 static int can_unlnk = 0; /* do we unlink null archives? */
91 const char *arcname; /* printable name of archive */
92 const char *gzip_program; /* name of gzip program */
93 static pid_t zpid = -1; /* pid of child process */
94 time_t starttime; /* time the run started */
95 int force_one_volume; /* 1 if we ignore volume changes */
96
97 static int get_phys(void);
98 extern sigset_t s_mask;
99 static void ar_start_gzip(int, const char *, int);
100 static const char *timefmt(char *, size_t, off_t, time_t);
101 static const char *sizefmt(char *, size_t, off_t);
102
103 #ifdef SUPPORT_RMT
104 #ifdef SYS_NO_RESTART
105 static int rmtread_with_restart(int, void *, int);
106 static int rmtwrite_with_restart(int, void *, int);
107 #else
108 #define rmtread_with_restart(a, b, c) rmtread((a), (b), (c))
109 #define rmtwrite_with_restart(a, b, c) rmtwrite((a), (b), (c))
110 #endif
111 #endif /* SUPPORT_RMT */
112
113 /*
114 * ar_open()
115 * Opens the next archive volume. Determines the type of the device and
116 * sets up block sizes as required by the archive device and the format.
117 * Note: we may be called with name == NULL on the first open only.
118 * Return:
119 * -1 on failure, 0 otherwise
120 */
121
122 int
123 ar_open(const char *name)
124 {
125 struct mtget mb;
126
127 if (arfd != -1)
128 (void)close(arfd);
129 arfd = -1;
130 can_unlnk = did_io = io_ok = invld_rec = 0;
131 artyp = ISREG;
132 flcnt = 0;
133
134 #ifdef SUPPORT_RMT
135 if (strchr(name, ':') != NULL && !forcelocal) {
136 artyp = ISRMT;
137 if ((arfd = rmtopen(name, O_RDWR, DMOD)) == -1) {
138 syswarn(0, errno, "Failed open on %s", name);
139 return -1;
140 }
141 blksz = rdblksz = 8192;
142 lstrval = 1;
143 return 0;
144 }
145 #endif /* SUPPORT_RMT */
146
147 /*
148 * open based on overall operation mode
149 */
150 switch (act) {
151 case LIST:
152 case EXTRACT:
153 if (name == NULL) {
154 arfd = STDIN_FILENO;
155 arcname = STDN;
156 } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
157 syswarn(0, errno, "Failed open to read on %s", name);
158 if (arfd != -1 && gzip_program != NULL)
159 ar_start_gzip(arfd, gzip_program, 0);
160 break;
161 case ARCHIVE:
162 if (name == NULL) {
163 arfd = STDOUT_FILENO;
164 arcname = STDO;
165 } else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
166 syswarn(0, errno, "Failed open to write on %s", name);
167 else
168 can_unlnk = 1;
169 if (arfd != -1 && gzip_program != NULL)
170 ar_start_gzip(arfd, gzip_program, 1);
171 break;
172 case APPND:
173 if (name == NULL) {
174 arfd = STDOUT_FILENO;
175 arcname = STDO;
176 } else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
177 syswarn(0, errno, "Failed open to read/write on %s",
178 name);
179 break;
180 case COPY:
181 /*
182 * arfd not used in COPY mode
183 */
184 arcname = "<NONE>";
185 lstrval = 1;
186 return(0);
187 }
188 if (arfd < 0)
189 return(-1);
190
191 if (chdname != NULL)
192 if (chdir(chdname) != 0)
193 syswarn(1, errno, "Failed chdir to %s", chdname);
194 /*
195 * set up is based on device type
196 */
197 if (fstat(arfd, &arsb) < 0) {
198 syswarn(0, errno, "Failed stat on %s", arcname);
199 (void)close(arfd);
200 arfd = -1;
201 can_unlnk = 0;
202 return(-1);
203 }
204 if (S_ISDIR(arsb.st_mode)) {
205 tty_warn(0, "Cannot write an archive on top of a directory %s",
206 arcname);
207 (void)close(arfd);
208 arfd = -1;
209 can_unlnk = 0;
210 return(-1);
211 }
212
213 if (S_ISCHR(arsb.st_mode))
214 artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
215 else if (S_ISBLK(arsb.st_mode))
216 artyp = ISBLK;
217 else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
218 artyp = ISPIPE;
219 else
220 artyp = ISREG;
221
222 /*
223 * make sure we beyond any doubt that we only can unlink regular files
224 * we created
225 */
226 if (artyp != ISREG)
227 can_unlnk = 0;
228
229 /*
230 * if we are writing, we are done
231 */
232 if (act == ARCHIVE) {
233 blksz = rdblksz = wrblksz;
234 lstrval = 1;
235 return(0);
236 }
237
238 /*
239 * set default blksz on read. APPNDs writes rdblksz on the last volume
240 * On all new archive volumes, we shift to wrblksz (if the user
241 * specified one, otherwize we will continue to use rdblksz). We
242 * must to set blocksize based on what kind of device the archive is
243 * stored.
244 */
245 switch(artyp) {
246 case ISTAPE:
247 /*
248 * Tape drives come in at least two flavors. Those that support
249 * variable sized records and those that have fixed sized
250 * records. They must be treated differently. For tape drives
251 * that support variable sized records, we must make large
252 * reads to make sure we get the entire record, otherwise we
253 * will just get the first part of the record (up to size we
254 * asked). Tapes with fixed sized records may or may not return
255 * multiple records in a single read. We really do not care
256 * what the physical record size is UNLESS we are going to
257 * append. (We will need the physical block size to rewrite
258 * the trailer). Only when we are appending do we go to the
259 * effort to figure out the true PHYSICAL record size.
260 */
261 blksz = rdblksz = MAXBLK;
262 break;
263 case ISPIPE:
264 case ISBLK:
265 case ISCHR:
266 /*
267 * Blocksize is not a major issue with these devices (but must
268 * be kept a multiple of 512). If the user specified a write
269 * block size, we use that to read. Under append, we must
270 * always keep blksz == rdblksz. Otherwise we go ahead and use
271 * the device optimal blocksize as (and if) returned by stat
272 * and if it is within pax specs.
273 */
274 if ((act == APPND) && wrblksz) {
275 blksz = rdblksz = wrblksz;
276 break;
277 }
278
279 if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
280 ((arsb.st_blksize % BLKMULT) == 0))
281 rdblksz = arsb.st_blksize;
282 else
283 rdblksz = DEVBLK;
284 /*
285 * For performance go for large reads when we can without harm
286 */
287 if ((act == APPND) || (artyp == ISCHR))
288 blksz = rdblksz;
289 else
290 blksz = MAXBLK;
291 break;
292 case ISREG:
293 /*
294 * if the user specified wrblksz works, use it. Under appends
295 * we must always keep blksz == rdblksz
296 */
297 if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
298 blksz = rdblksz = wrblksz;
299 break;
300 }
301 /*
302 * See if we can find the blocking factor from the file size
303 */
304 for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
305 if ((arsb.st_size % rdblksz) == 0)
306 break;
307 /*
308 * When we cannot find a match, we may have a flawed archive.
309 */
310 if (rdblksz <= 0)
311 rdblksz = FILEBLK;
312 /*
313 * for performance go for large reads when we can
314 */
315 if (act == APPND)
316 blksz = rdblksz;
317 else
318 blksz = MAXBLK;
319 break;
320 default:
321 /*
322 * should never happen, worse case, slow...
323 */
324 blksz = rdblksz = BLKMULT;
325 break;
326 }
327 lstrval = 1;
328 return(0);
329 }
330
331 /*
332 * ar_close()
333 * closes archive device, increments volume number, and prints i/o summary
334 */
335 void
336 ar_close(void)
337 {
338 if (arfd < 0) {
339 did_io = io_ok = flcnt = 0;
340 return;
341 }
342
343
344 /*
345 * Close archive file. This may take a LONG while on tapes (we may be
346 * forced to wait for the rewind to complete) so tell the user what is
347 * going on (this avoids the user hitting control-c thinking pax is
348 * broken).
349 */
350 if (vflag && (artyp == ISTAPE)) {
351 if (vfpart)
352 (void)putc('\n', listf);
353 (void)fprintf(listf,
354 "%s: Waiting for tape drive close to complete...",
355 argv0);
356 (void)fflush(listf);
357 }
358
359 /*
360 * if nothing was written to the archive (and we created it), we remove
361 * it
362 */
363 if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
364 (arsb.st_size == 0)) {
365 (void)unlink(arcname);
366 can_unlnk = 0;
367 }
368
369 /*
370 * for a quick extract/list, pax frequently exits before the child
371 * process is done
372 */
373 if ((act == LIST || act == EXTRACT) && nflag && zpid > 0) {
374 int status;
375 kill(zpid, SIGINT);
376 waitpid(zpid, &status, 0);
377 }
378
379 #ifdef SUPPORT_RMT
380 if (artyp == ISRMT)
381 (void)rmtclose(arfd);
382 else
383 #endif /* SUPPORT_RMT */
384 (void)close(arfd);
385
386 if (vflag && (artyp == ISTAPE)) {
387 (void)fputs("done.\n", listf);
388 vfpart = 0;
389 (void)fflush(listf);
390 }
391 arfd = -1;
392
393 if (!io_ok && !did_io) {
394 flcnt = 0;
395 return;
396 }
397 did_io = io_ok = 0;
398
399 /*
400 * The volume number is only increased when the last device has data
401 * and we have already determined the archive format.
402 */
403 if (frmt != NULL)
404 ++arvol;
405
406 if (!vflag) {
407 flcnt = 0;
408 return;
409 }
410
411 /*
412 * Print out a summary of I/O for this archive volume.
413 */
414 if (vfpart) {
415 (void)putc('\n', listf);
416 vfpart = 0;
417 }
418 /*
419 * If we have not determined the format yet, we just say how many bytes
420 * we have skipped over looking for a header to id. there is no way we
421 * could have written anything yet.
422 */
423 if (frmt == NULL) {
424 (void)fprintf(listf, "%s: unknown format, " OFFT_F
425 " bytes skipped.\n", argv0, rdcnt);
426 (void)fflush(listf);
427 flcnt = 0;
428 return;
429 }
430
431 if (strcmp(NM_CPIO, argv0) == 0) {
432 (void)fprintf(listf, OFFT_F " blocks\n",
433 (rdcnt ? rdcnt : wrcnt) / 5120);
434 } else if (strcmp(NM_TAR, argv0) != 0) {
435 (void)fprintf(listf,
436 "%s: %s vol %d, %lu files, " OFFT_F " bytes read, "
437 OFFT_F " bytes written.\n",
438 argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
439 }
440
441 ar_summary(0);
442
443 (void)fflush(listf);
444 flcnt = 0;
445 }
446
447 /*
448 * ar_drain()
449 * drain any archive format independent padding from an archive read
450 * from a socket or a pipe. This is to prevent the process on the
451 * other side of the pipe from getting a SIGPIPE (pax will stop
452 * reading an archive once a format dependent trailer is detected).
453 */
454 void
455 ar_drain(void)
456 {
457 int res;
458 char drbuf[MAXBLK];
459
460 /*
461 * we only drain from a pipe/socket. Other devices can be closed
462 * without reading up to end of file. We sure hope that pipe is closed
463 * on the other side so we will get an EOF.
464 */
465 if ((artyp != ISPIPE) || (lstrval <= 0))
466 return;
467
468 /*
469 * keep reading until pipe is drained
470 */
471 #ifdef SUPPORT_RMT
472 if (artyp == ISRMT) {
473 while ((res = rmtread_with_restart(arfd,
474 drbuf, sizeof(drbuf))) > 0)
475 continue;
476 } else {
477 #endif /* SUPPORT_RMT */
478 while ((res = read_with_restart(arfd,
479 drbuf, sizeof(drbuf))) > 0)
480 continue;
481 #ifdef SUPPORT_RMT
482 }
483 #endif /* SUPPORT_RMT */
484 lstrval = res;
485 }
486
487 /*
488 * ar_set_wr()
489 * Set up device right before switching from read to write in an append.
490 * device dependent code (if required) to do this should be added here.
491 * For all archive devices we are already positioned at the place we want
492 * to start writing when this routine is called.
493 * Return:
494 * 0 if all ready to write, -1 otherwise
495 */
496
497 int
498 ar_set_wr(void)
499 {
500 off_t cpos;
501
502 /*
503 * we must make sure the trailer is rewritten on append, ar_next()
504 * will stop us if the archive containing the trailer was not written
505 */
506 wr_trail = 0;
507
508 /*
509 * Add any device dependent code as required here
510 */
511 if (artyp != ISREG)
512 return(0);
513 /*
514 * Ok we have an archive in a regular file. If we were rewriting a
515 * file, we must get rid of all the stuff after the current offset
516 * (it was not written by pax).
517 */
518 if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
519 (ftruncate(arfd, cpos) < 0)) {
520 syswarn(1, errno, "Unable to truncate archive file");
521 return(-1);
522 }
523 return(0);
524 }
525
526 /*
527 * ar_app_ok()
528 * check if the last volume in the archive allows appends. We cannot check
529 * this until we are ready to write since there is no spec that says all
530 * volumes in a single archive have to be of the same type...
531 * Return:
532 * 0 if we can append, -1 otherwise.
533 */
534
535 int
536 ar_app_ok(void)
537 {
538 if (artyp == ISPIPE) {
539 tty_warn(1,
540 "Cannot append to an archive obtained from a pipe.");
541 return(-1);
542 }
543
544 if (!invld_rec)
545 return(0);
546 tty_warn(1,
547 "Cannot append, device record size %d does not support %s spec",
548 rdblksz, argv0);
549 return(-1);
550 }
551
552 #ifdef SYS_NO_RESTART
553 /*
554 * read_with_restart()
555 * Equivalent to read() but does retry on signals.
556 * This function is not needed on 4.2BSD and later.
557 * Return:
558 * Number of bytes written. -1 indicates an error.
559 */
560
561 int
562 read_with_restart(int fd, void *buf, int bsz)
563 {
564 int r;
565
566 while (((r = read(fd, buf, bsz)) < 0) && errno == EINTR)
567 continue;
568
569 return(r);
570 }
571
572 /*
573 * rmtread_with_restart()
574 * Equivalent to rmtread() but does retry on signals.
575 * This function is not needed on 4.2BSD and later.
576 * Return:
577 * Number of bytes written. -1 indicates an error.
578 */
579 static int
580 rmtread_with_restart(int fd, void *buf, int bsz)
581 {
582 int r;
583
584 while (((r = rmtread(fd, buf, bsz)) < 0) && errno == EINTR)
585 continue;
586
587 return(r);
588 }
589 #endif
590
591 /*
592 * xread()
593 * Equivalent to read() but does retry on partial read, which may occur
594 * on signals.
595 * Return:
596 * Number of bytes read. 0 for end of file, -1 for an error.
597 */
598
599 int
600 xread(int fd, void *buf, int bsz)
601 {
602 char *b = buf;
603 int nread = 0;
604 int r;
605
606 do {
607 #ifdef SUPPORT_RMT
608 if ((r = rmtread_with_restart(fd, b, bsz)) <= 0)
609 break;
610 #else
611 if ((r = read_with_restart(fd, b, bsz)) <= 0)
612 break;
613 #endif /* SUPPORT_RMT */
614 b += r;
615 bsz -= r;
616 nread += r;
617 } while (bsz > 0);
618
619 return(nread ? nread : r);
620 }
621
622 #ifdef SYS_NO_RESTART
623 /*
624 * write_with_restart()
625 * Equivalent to write() but does retry on signals.
626 * This function is not needed on 4.2BSD and later.
627 * Return:
628 * Number of bytes written. -1 indicates an error.
629 */
630
631 int
632 write_with_restart(int fd, void *buf, int bsz)
633 {
634 int r;
635
636 while (((r = write(fd, buf, bsz)) < 0) && errno == EINTR)
637 ;
638
639 return(r);
640 }
641
642 /*
643 * rmtwrite_with_restart()
644 * Equivalent to write() but does retry on signals.
645 * This function is not needed on 4.2BSD and later.
646 * Return:
647 * Number of bytes written. -1 indicates an error.
648 */
649
650 static int
651 rmtwrite_with_restart(int fd, void *buf, int bsz)
652 {
653 int r;
654
655 while (((r = rmtwrite(fd, buf, bsz)) < 0) && errno == EINTR)
656 ;
657
658 return(r);
659 }
660 #endif
661
662 /*
663 * xwrite()
664 * Equivalent to write() but does retry on partial write, which may occur
665 * on signals.
666 * Return:
667 * Number of bytes written. -1 indicates an error.
668 */
669
670 int
671 xwrite(int fd, void *buf, int bsz)
672 {
673 char *b = buf;
674 int written = 0;
675 int r;
676
677 do {
678 #ifdef SUPPORT_RMT
679 if ((r = rmtwrite_with_restart(fd, b, bsz)) <= 0)
680 break;
681 #else
682 if ((r = write_with_restart(fd, b, bsz)) <= 0)
683 break;
684 #endif /* SUPPORT_RMT */
685 b += r;
686 bsz -= r;
687 written += r;
688 } while (bsz > 0);
689
690 return(written ? written : r);
691 }
692
693 /*
694 * ar_read()
695 * read up to a specified number of bytes from the archive into the
696 * supplied buffer. When dealing with tapes we may not always be able to
697 * read what we want.
698 * Return:
699 * Number of bytes in buffer. 0 for end of file, -1 for a read error.
700 */
701
702 int
703 ar_read(char *buf, int cnt)
704 {
705 int res = 0;
706
707 /*
708 * if last i/o was in error, no more reads until reset or new volume
709 */
710 if (lstrval <= 0)
711 return(lstrval);
712
713 /*
714 * how we read must be based on device type
715 */
716 switch (artyp) {
717 #ifdef SUPPORT_RMT
718 case ISRMT:
719 if ((res = rmtread_with_restart(arfd, buf, cnt)) > 0) {
720 io_ok = 1;
721 return res;
722 }
723 break;
724 #endif /* SUPPORT_RMT */
725 case ISTAPE:
726 if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
727 /*
728 * CAUTION: tape systems may not always return the same
729 * sized records so we leave blksz == MAXBLK. The
730 * physical record size that a tape drive supports is
731 * very hard to determine in a uniform and portable
732 * manner.
733 */
734 io_ok = 1;
735 if (res != rdblksz) {
736 /*
737 * Record size changed. If this is happens on
738 * any record after the first, we probably have
739 * a tape drive which has a fixed record size
740 * we are getting multiple records in a single
741 * read). Watch out for record blocking that
742 * violates pax spec (must be a multiple of
743 * BLKMULT).
744 */
745 rdblksz = res;
746 if (rdblksz % BLKMULT)
747 invld_rec = 1;
748 }
749 return(res);
750 }
751 break;
752 case ISREG:
753 case ISBLK:
754 case ISCHR:
755 case ISPIPE:
756 default:
757 /*
758 * Files are so easy to deal with. These other things cannot
759 * be trusted at all. So when we are dealing with character
760 * devices and pipes we just take what they have ready for us
761 * and return. Trying to do anything else with them runs the
762 * risk of failure.
763 */
764 if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
765 io_ok = 1;
766 return(res);
767 }
768 break;
769 }
770
771 /*
772 * We are in trouble at this point, something is broken...
773 */
774 lstrval = res;
775 if (res < 0)
776 syswarn(1, errno, "Failed read on archive volume %d", arvol);
777 else if (!is_oldgnutar)
778 tty_warn(0, "End of archive volume %d reached", arvol);
779 return(res);
780 }
781
782 /*
783 * ar_write()
784 * Write a specified number of bytes in supplied buffer to the archive
785 * device so it appears as a single "block". Deals with errors and tries
786 * to recover when faced with short writes.
787 * Return:
788 * Number of bytes written. 0 indicates end of volume reached and with no
789 * flaws (as best that can be detected). A -1 indicates an unrecoverable
790 * error in the archive occurred.
791 */
792
793 int
794 ar_write(char *buf, int bsz)
795 {
796 int res;
797 off_t cpos;
798
799 /*
800 * do not allow pax to create a "bad" archive. Once a write fails on
801 * an archive volume prevent further writes to it.
802 */
803 if (lstrval <= 0)
804 return(lstrval);
805
806 if ((res = xwrite(arfd, buf, bsz)) == bsz) {
807 wr_trail = 1;
808 io_ok = 1;
809 return(bsz);
810 }
811 /*
812 * write broke, see what we can do with it. We try to send any partial
813 * writes that may violate pax spec to the next archive volume.
814 */
815 if (res < 0)
816 lstrval = res;
817 else
818 lstrval = 0;
819
820 switch (artyp) {
821 case ISREG:
822 if ((res > 0) && (res % BLKMULT)) {
823 /*
824 * try to fix up partial writes which are not BLKMULT
825 * in size by forcing the runt record to next archive
826 * volume
827 */
828 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
829 break;
830 cpos -= (off_t)res;
831 if (ftruncate(arfd, cpos) < 0)
832 break;
833 res = lstrval = 0;
834 break;
835 }
836 if (res >= 0)
837 break;
838 /*
839 * if file is out of space, handle it like a return of 0
840 */
841 if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
842 res = lstrval = 0;
843 break;
844 case ISTAPE:
845 case ISCHR:
846 case ISBLK:
847 #ifdef SUPPORT_RMT
848 case ISRMT:
849 #endif /* SUPPORT_RMT */
850 if (res >= 0)
851 break;
852 if (errno == EACCES) {
853 tty_warn(0,
854 "Write failed, archive is write protected.");
855 res = lstrval = 0;
856 return(0);
857 }
858 /*
859 * see if we reached the end of media, if so force a change to
860 * the next volume
861 */
862 if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
863 res = lstrval = 0;
864 break;
865 case ISPIPE:
866 default:
867 /*
868 * we cannot fix errors to these devices
869 */
870 break;
871 }
872
873 /*
874 * Better tell the user the bad news...
875 * if this is a block aligned archive format, we may have a bad archive
876 * if the format wants the header to start at a BLKMULT boundary. While
877 * we can deal with the mis-aligned data, it violates spec and other
878 * archive readers will likely fail. if the format is not block
879 * aligned, the user may be lucky (and the archive is ok).
880 */
881 if (res >= 0) {
882 if (res > 0)
883 wr_trail = 1;
884 io_ok = 1;
885 }
886
887 /*
888 * If we were trying to rewrite the trailer and it didn't work, we
889 * must quit right away.
890 */
891 if (!wr_trail && (res <= 0)) {
892 tty_warn(1,
893 "Unable to append, trailer re-write failed. Quitting.");
894 return(res);
895 }
896
897 if (res == 0)
898 tty_warn(0, "End of archive volume %d reached", arvol);
899 else if (res < 0)
900 syswarn(1, errno, "Failed write to archive volume: %d", arvol);
901 else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
902 tty_warn(0,
903 "WARNING: partial archive write. Archive MAY BE FLAWED");
904 else
905 tty_warn(1,"WARNING: partial archive write. Archive IS FLAWED");
906 return(res);
907 }
908
909 /*
910 * ar_rdsync()
911 * Try to move past a bad spot on a flawed archive as needed to continue
912 * I/O. Clears error flags to allow I/O to continue.
913 * Return:
914 * 0 when ok to try i/o again, -1 otherwise.
915 */
916
917 int
918 ar_rdsync(void)
919 {
920 long fsbz;
921 off_t cpos;
922 off_t mpos;
923 struct mtop mb;
924
925 /*
926 * Fail resync attempts at user request (done) or this is going to be
927 * an update/append to a existing archive. if last i/o hit media end,
928 * we need to go to the next volume not try a resync
929 */
930 if ((done > 0) || (lstrval == 0))
931 return(-1);
932
933 if ((act == APPND) || (act == ARCHIVE)) {
934 tty_warn(1, "Cannot allow updates to an archive with flaws.");
935 return(-1);
936 }
937 if (io_ok)
938 did_io = 1;
939
940 switch(artyp) {
941 #ifdef SUPPORT_RMT
942 case ISRMT:
943 #endif /* SUPPORT_RMT */
944 case ISTAPE:
945 /*
946 * if the last i/o was a successful data transfer, we assume
947 * the fault is just a bad record on the tape that we are now
948 * past. If we did not get any data since the last resync try
949 * to move the tape forward one PHYSICAL record past any
950 * damaged tape section. Some tape drives are stubborn and need
951 * to be pushed.
952 */
953 if (io_ok) {
954 io_ok = 0;
955 lstrval = 1;
956 break;
957 }
958 mb.mt_op = MTFSR;
959 mb.mt_count = 1;
960 #ifdef SUPPORT_RMT
961 if (artyp == ISRMT) {
962 if (rmtioctl(arfd, MTIOCTOP, &mb) < 0)
963 break;
964 } else {
965 #endif /* SUPPORT_RMT */
966 if (ioctl(arfd, MTIOCTOP, &mb) < 0)
967 break;
968 #ifdef SUPPORT_RMT
969 }
970 #endif /* SUPPORT_RMT */
971 lstrval = 1;
972 break;
973 case ISREG:
974 case ISCHR:
975 case ISBLK:
976 /*
977 * try to step over the bad part of the device.
978 */
979 io_ok = 0;
980 if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
981 fsbz = BLKMULT;
982 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
983 break;
984 mpos = fsbz - (cpos % (off_t)fsbz);
985 if (lseek(arfd, mpos, SEEK_CUR) < 0)
986 break;
987 lstrval = 1;
988 break;
989 case ISPIPE:
990 default:
991 /*
992 * cannot recover on these archive device types
993 */
994 io_ok = 0;
995 break;
996 }
997 if (lstrval <= 0) {
998 tty_warn(1, "Unable to recover from an archive read failure.");
999 return(-1);
1000 }
1001 tty_warn(0, "Attempting to recover from an archive read failure.");
1002 return(0);
1003 }
1004
1005 /*
1006 * ar_fow()
1007 * Move the I/O position within the archive forward the specified number of
1008 * bytes as supported by the device. If we cannot move the requested
1009 * number of bytes, return the actual number of bytes moved in skipped.
1010 * Return:
1011 * 0 if moved the requested distance, -1 on complete failure, 1 on
1012 * partial move (the amount moved is in skipped)
1013 */
1014
1015 int
1016 ar_fow(off_t sksz, off_t *skipped)
1017 {
1018 off_t cpos;
1019 off_t mpos;
1020
1021 *skipped = 0;
1022 if (sksz <= 0)
1023 return(0);
1024
1025 /*
1026 * we cannot move forward at EOF or error
1027 */
1028 if (lstrval <= 0)
1029 return(lstrval);
1030
1031 /*
1032 * Safer to read forward on devices where it is hard to find the end of
1033 * the media without reading to it. With tapes we cannot be sure of the
1034 * number of physical blocks to skip (we do not know physical block
1035 * size at this point), so we must only read forward on tapes!
1036 */
1037 if (artyp == ISTAPE || artyp == ISPIPE
1038 #ifdef SUPPORT_RMT
1039 || artyp == ISRMT
1040 #endif /* SUPPORT_RMT */
1041 )
1042 return(0);
1043
1044 /*
1045 * figure out where we are in the archive
1046 */
1047 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
1048 /*
1049 * we can be asked to move farther than there are bytes in this
1050 * volume, if so, just go to file end and let normal buf_fill()
1051 * deal with the end of file (it will go to next volume by
1052 * itself)
1053 */
1054 mpos = cpos + sksz;
1055 if (artyp == ISREG && mpos > arsb.st_size)
1056 mpos = arsb.st_size;
1057 if ((mpos = lseek(arfd, mpos, SEEK_SET)) >= 0) {
1058 *skipped = mpos - cpos;
1059 return(0);
1060 }
1061 } else {
1062 if (artyp != ISREG)
1063 return(0); /* non-seekable device */
1064 }
1065 syswarn(1, errno, "Forward positioning operation on archive failed");
1066 lstrval = -1;
1067 return(-1);
1068 }
1069
1070 /*
1071 * ar_rev()
1072 * move the i/o position within the archive backwards the specified byte
1073 * count as supported by the device. With tapes drives we RESET rdblksz to
1074 * the PHYSICAL blocksize.
1075 * NOTE: We should only be called to move backwards so we can rewrite the
1076 * last records (the trailer) of an archive (APPEND).
1077 * Return:
1078 * 0 if moved the requested distance, -1 on complete failure
1079 */
1080
1081 int
1082 ar_rev(off_t sksz)
1083 {
1084 off_t cpos;
1085 struct mtop mb;
1086 int phyblk;
1087
1088 /*
1089 * make sure we do not have try to reverse on a flawed archive
1090 */
1091 if (lstrval < 0)
1092 return(lstrval);
1093
1094 switch(artyp) {
1095 case ISPIPE:
1096 if (sksz <= 0)
1097 break;
1098 /*
1099 * cannot go backwards on these critters
1100 */
1101 tty_warn(1, "Reverse positioning on pipes is not supported.");
1102 lstrval = -1;
1103 return(-1);
1104 case ISREG:
1105 case ISBLK:
1106 case ISCHR:
1107 default:
1108 if (sksz <= 0)
1109 break;
1110
1111 /*
1112 * For things other than files, backwards movement has a very
1113 * high probability of failure as we really do not know the
1114 * true attributes of the device we are talking to (the device
1115 * may not even have the ability to lseek() in any direction).
1116 * First we figure out where we are in the archive.
1117 */
1118 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
1119 syswarn(1, errno,
1120 "Unable to obtain current archive byte offset");
1121 lstrval = -1;
1122 return(-1);
1123 }
1124
1125 /*
1126 * we may try to go backwards past the start when the archive
1127 * is only a single record. If this hapens and we are on a
1128 * multi volume archive, we need to go to the end of the
1129 * previous volume and continue our movement backwards from
1130 * there.
1131 */
1132 if ((cpos -= sksz) < (off_t)0L) {
1133 if (arvol > 1) {
1134 /*
1135 * this should never happen
1136 */
1137 tty_warn(1,
1138 "Reverse position on previous volume.");
1139 lstrval = -1;
1140 return(-1);
1141 }
1142 cpos = (off_t)0L;
1143 }
1144 if (lseek(arfd, cpos, SEEK_SET) < 0) {
1145 syswarn(1, errno, "Unable to seek archive backwards");
1146 lstrval = -1;
1147 return(-1);
1148 }
1149 break;
1150 case ISTAPE:
1151 #ifdef SUPPORT_RMT
1152 case ISRMT:
1153 #endif /* SUPPORT_RMT */
1154 /*
1155 * Calculate and move the proper number of PHYSICAL tape
1156 * blocks. If the sksz is not an even multiple of the physical
1157 * tape size, we cannot do the move (this should never happen).
1158 * (We also cannot handler trailers spread over two vols).
1159 * get_phys() also makes sure we are in front of the filemark.
1160 */
1161 if ((phyblk = get_phys()) <= 0) {
1162 lstrval = -1;
1163 return(-1);
1164 }
1165
1166 /*
1167 * make sure future tape reads only go by physical tape block
1168 * size (set rdblksz to the real size).
1169 */
1170 rdblksz = phyblk;
1171
1172 /*
1173 * if no movement is required, just return (we must be after
1174 * get_phys() so the physical blocksize is properly set)
1175 */
1176 if (sksz <= 0)
1177 break;
1178
1179 /*
1180 * ok we have to move. Make sure the tape drive can do it.
1181 */
1182 if (sksz % phyblk) {
1183 tty_warn(1,
1184 "Tape drive unable to backspace requested amount");
1185 lstrval = -1;
1186 return(-1);
1187 }
1188
1189 /*
1190 * move backwards the requested number of bytes
1191 */
1192 mb.mt_op = MTBSR;
1193 mb.mt_count = sksz/phyblk;
1194 if (
1195 #ifdef SUPPORT_RMT
1196 rmtioctl(arfd, MTIOCTOP, &mb)
1197 #else
1198 ioctl(arfd, MTIOCTOP, &mb)
1199 #endif /* SUPPORT_RMT */
1200 < 0) {
1201 syswarn(1,errno, "Unable to backspace tape %ld blocks.",
1202 (long) mb.mt_count);
1203 lstrval = -1;
1204 return(-1);
1205 }
1206 break;
1207 }
1208 lstrval = 1;
1209 return(0);
1210 }
1211
1212 /*
1213 * get_phys()
1214 * Determine the physical block size on a tape drive. We need the physical
1215 * block size so we know how many bytes we skip over when we move with
1216 * mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when
1217 * return.
1218 * This is one really SLOW routine...
1219 * Return:
1220 * physical block size if ok (ok > 0), -1 otherwise
1221 */
1222
1223 static int
1224 get_phys(void)
1225 {
1226 int padsz = 0;
1227 int res;
1228 int phyblk;
1229 struct mtop mb;
1230 char scbuf[MAXBLK];
1231
1232 /*
1233 * move to the file mark, and then back up one record and read it.
1234 * this should tell us the physical record size the tape is using.
1235 */
1236 if (lstrval == 1) {
1237 /*
1238 * we know we are at file mark when we get back a 0 from
1239 * read()
1240 */
1241 #ifdef SUPPORT_RMT
1242 while ((res = rmtread_with_restart(arfd,
1243 scbuf, sizeof(scbuf))) > 0)
1244 #else
1245 while ((res = read_with_restart(arfd,
1246 scbuf, sizeof(scbuf))) > 0)
1247 #endif /* SUPPORT_RMT */
1248 padsz += res;
1249 if (res < 0) {
1250 syswarn(1, errno, "Unable to locate tape filemark.");
1251 return(-1);
1252 }
1253 }
1254
1255 /*
1256 * move backwards over the file mark so we are at the end of the
1257 * last record.
1258 */
1259 mb.mt_op = MTBSF;
1260 mb.mt_count = 1;
1261 if (
1262 #ifdef SUPPORT_RMT
1263 rmtioctl(arfd, MTIOCTOP, &mb)
1264 #else
1265 ioctl(arfd, MTIOCTOP, &mb)
1266 #endif /* SUPPORT_RMT */
1267 < 0) {
1268 syswarn(1, errno, "Unable to backspace over tape filemark.");
1269 return(-1);
1270 }
1271
1272 /*
1273 * move backwards so we are in front of the last record and read it to
1274 * get physical tape blocksize.
1275 */
1276 mb.mt_op = MTBSR;
1277 mb.mt_count = 1;
1278 if (
1279 #ifdef SUPPORT_RMT
1280 rmtioctl(arfd, MTIOCTOP, &mb)
1281 #else
1282 ioctl(arfd, MTIOCTOP, &mb)
1283 #endif /* SUPPORT_RMT */
1284 < 0) {
1285 syswarn(1, errno, "Unable to backspace over last tape block.");
1286 return(-1);
1287 }
1288 if ((phyblk =
1289 #ifdef SUPPORT_RMT
1290 rmtread_with_restart(arfd, scbuf, sizeof(scbuf))
1291 #else
1292 read_with_restart(arfd, scbuf, sizeof(scbuf))
1293 #endif /* SUPPORT_RMT */
1294 ) <= 0) {
1295 syswarn(1, errno, "Cannot determine archive tape blocksize.");
1296 return(-1);
1297 }
1298
1299 /*
1300 * read forward to the file mark, then back up in front of the filemark
1301 * (this is a bit paranoid, but should be safe to do).
1302 */
1303 while ((res =
1304 #ifdef SUPPORT_RMT
1305 rmtread_with_restart(arfd, scbuf, sizeof(scbuf))
1306 #else
1307 read_with_restart(arfd, scbuf, sizeof(scbuf))
1308 #endif /* SUPPORT_RMT */
1309 ) > 0)
1310 ;
1311 if (res < 0) {
1312 syswarn(1, errno, "Unable to locate tape filemark.");
1313 return(-1);
1314 }
1315 mb.mt_op = MTBSF;
1316 mb.mt_count = 1;
1317 if (
1318 #ifdef SUPPORT_RMT
1319 rmtioctl(arfd, MTIOCTOP, &mb)
1320 #else
1321 ioctl(arfd, MTIOCTOP, &mb)
1322 #endif /* SUPPORT_RMT */
1323 < 0) {
1324 syswarn(1, errno, "Unable to backspace over tape filemark.");
1325 return(-1);
1326 }
1327
1328 /*
1329 * set lstrval so we know that the filemark has not been seen
1330 */
1331 lstrval = 1;
1332
1333 /*
1334 * return if there was no padding
1335 */
1336 if (padsz == 0)
1337 return(phyblk);
1338
1339 /*
1340 * make sure we can move backwards over the padding. (this should
1341 * never fail).
1342 */
1343 if (padsz % phyblk) {
1344 tty_warn(1, "Tape drive unable to backspace requested amount");
1345 return(-1);
1346 }
1347
1348 /*
1349 * move backwards over the padding so the head is where it was when
1350 * we were first called (if required).
1351 */
1352 mb.mt_op = MTBSR;
1353 mb.mt_count = padsz/phyblk;
1354 if (
1355 #ifdef SUPPORT_RMT
1356 rmtioctl(arfd, MTIOCTOP, &mb)
1357 #else
1358 ioctl(arfd, MTIOCTOP, &mb)
1359 #endif /* SUPPORT_RMT */
1360 < 0) {
1361 syswarn(1,errno,"Unable to backspace tape over %ld pad blocks",
1362 (long)mb.mt_count);
1363 return(-1);
1364 }
1365 return(phyblk);
1366 }
1367
1368 /*
1369 * ar_next()
1370 * prompts the user for the next volume in this archive. For some devices
1371 * we may allow the media to be changed. Otherwise a new archive is
1372 * prompted for. By pax spec, if there is no controlling tty or an eof is
1373 * read on tty input, we must quit pax.
1374 * Return:
1375 * 0 when ready to continue, -1 when all done
1376 */
1377
1378 int
1379 ar_next(void)
1380 {
1381 char buf[PAXPATHLEN+2];
1382 static int freeit = 0;
1383 sigset_t o_mask;
1384
1385 /*
1386 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
1387 * things like writing EOF etc will be done) (Watch out ar_close() can
1388 * also be called via a signal handler, so we must prevent a race.
1389 */
1390 if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
1391 syswarn(0, errno, "Unable to set signal mask");
1392 ar_close();
1393 if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
1394 syswarn(0, errno, "Unable to restore signal mask");
1395
1396 if (done || !wr_trail || is_oldgnutar || force_one_volume)
1397 return(-1);
1398
1399 tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
1400
1401 /*
1402 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
1403 * the name), the user will be forced to type it in.
1404 */
1405 if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
1406 && (artyp != ISPIPE)) {
1407 if (artyp == ISTAPE
1408 #ifdef SUPPORT_RMT
1409 || artyp == ISRMT
1410 #endif /* SUPPORT_RMT */
1411 ) {
1412 tty_prnt("%s ready for archive tape volume: %d\n",
1413 arcname, arvol);
1414 tty_prnt("Load the NEXT TAPE on the tape drive");
1415 } else {
1416 tty_prnt("%s ready for archive volume: %d\n",
1417 arcname, arvol);
1418 tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
1419 }
1420
1421 if ((act == ARCHIVE) || (act == APPND))
1422 tty_prnt(" and make sure it is WRITE ENABLED.\n");
1423 else
1424 tty_prnt("\n");
1425
1426 for(;;) {
1427 tty_prnt("Type \"y\" to continue, \".\" to quit %s,",
1428 argv0);
1429 tty_prnt(" or \"s\" to switch to new device.\nIf you");
1430 tty_prnt(" cannot change storage media, type \"s\"\n");
1431 tty_prnt("Is the device ready and online? > ");
1432
1433 if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
1434 done = 1;
1435 lstrval = -1;
1436 tty_prnt("Quitting %s!\n", argv0);
1437 vfpart = 0;
1438 return(-1);
1439 }
1440
1441 if ((buf[0] == '\0') || (buf[1] != '\0')) {
1442 tty_prnt("%s unknown command, try again\n",buf);
1443 continue;
1444 }
1445
1446 switch (buf[0]) {
1447 case 'y':
1448 case 'Y':
1449 /*
1450 * we are to continue with the same device
1451 */
1452 if (ar_open(arcname) >= 0)
1453 return(0);
1454 tty_prnt("Cannot re-open %s, try again\n",
1455 arcname);
1456 continue;
1457 case 's':
1458 case 'S':
1459 /*
1460 * user wants to open a different device
1461 */
1462 tty_prnt("Switching to a different archive\n");
1463 break;
1464 default:
1465 tty_prnt("%s unknown command, try again\n",buf);
1466 continue;
1467 }
1468 break;
1469 }
1470 } else
1471 tty_prnt("Ready for archive volume: %d\n", arvol);
1472
1473 /*
1474 * have to go to a different archive
1475 */
1476 for (;;) {
1477 tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);
1478 tty_prnt("Archive name > ");
1479
1480 if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
1481 done = 1;
1482 lstrval = -1;
1483 tty_prnt("Quitting %s!\n", argv0);
1484 vfpart = 0;
1485 return(-1);
1486 }
1487 if (buf[0] == '\0') {
1488 tty_prnt("Empty file name, try again\n");
1489 continue;
1490 }
1491 if (!strcmp(buf, "..")) {
1492 tty_prnt("Illegal file name: .. try again\n");
1493 continue;
1494 }
1495 if (strlen(buf) > PAXPATHLEN) {
1496 tty_prnt("File name too long, try again\n");
1497 continue;
1498 }
1499
1500 /*
1501 * try to open new archive
1502 */
1503 if (ar_open(buf) >= 0) {
1504 if (freeit) {
1505 (void)free((char *)arcname);
1506 freeit = 0;
1507 }
1508 if ((arcname = strdup(buf)) == NULL) {
1509 done = 1;
1510 lstrval = -1;
1511 tty_warn(0, "Cannot save archive name.");
1512 return(-1);
1513 }
1514 freeit = 1;
1515 break;
1516 }
1517 tty_prnt("Cannot open %s, try again\n", buf);
1518 continue;
1519 }
1520 return(0);
1521 }
1522
1523 /*
1524 * ar_start_gzip()
1525 * starts the gzip compression/decompression process as a child, using magic
1526 * to keep the fd the same in the calling function (parent).
1527 */
1528 void
1529 ar_start_gzip(int fd, const char *gzp, int wr)
1530 {
1531 int fds[2];
1532 const char *gzip_flags;
1533
1534 if (pipe(fds) < 0)
1535 err(1, "could not pipe");
1536 zpid = fork();
1537 if (zpid < 0)
1538 err(1, "could not fork");
1539
1540 /* parent */
1541 if (zpid) {
1542 if (wr)
1543 dup2(fds[1], fd);
1544 else
1545 dup2(fds[0], fd);
1546 close(fds[0]);
1547 close(fds[1]);
1548 } else {
1549 if (wr) {
1550 dup2(fds[0], STDIN_FILENO);
1551 dup2(fd, STDOUT_FILENO);
1552 gzip_flags = "-c";
1553 } else {
1554 dup2(fds[1], STDOUT_FILENO);
1555 dup2(fd, STDIN_FILENO);
1556 gzip_flags = "-dc";
1557 }
1558 close(fds[0]);
1559 close(fds[1]);
1560 if (execlp(gzp, gzp, gzip_flags, NULL) < 0)
1561 err(1, "could not exec");
1562 /* NOTREACHED */
1563 }
1564 }
1565
1566 static const char *
1567 timefmt(buf, size, sz, tm)
1568 char *buf;
1569 size_t size;
1570 off_t sz;
1571 time_t tm;
1572 {
1573 (void)snprintf(buf, size, "%lu secs (" OFFT_F " bytes/sec)",
1574 (unsigned long)tm, (OFFT_T)(sz / tm));
1575 return buf;
1576 }
1577
1578 static const char *
1579 sizefmt(buf, size, sz)
1580 char *buf;
1581 size_t size;
1582 off_t sz;
1583 {
1584 (void)snprintf(buf, size, OFFT_F " bytes", (OFFT_T)sz);
1585 return buf;
1586 }
1587
1588 void
1589 ar_summary(int n)
1590 {
1591 time_t secs;
1592 int len;
1593 char buf[MAXPATHLEN];
1594 char tbuf[MAXPATHLEN/4];
1595 char s1buf[MAXPATHLEN/8];
1596 char s2buf[MAXPATHLEN/8];
1597 FILE *outf;
1598
1599 if (act == LIST)
1600 outf = stdout;
1601 else
1602 outf = stderr;
1603
1604 /*
1605 * If we are called from a signal (n != 0), use snprintf(3) so that we
1606 * don't reenter stdio(3).
1607 */
1608 (void)time(&secs);
1609 if ((secs -= starttime) == 0)
1610 secs = 1;
1611
1612 /*
1613 * If we have not determined the format yet, we just say how many bytes
1614 * we have skipped over looking for a header to id. there is no way we
1615 * could have written anything yet.
1616 */
1617 if (frmt == NULL) {
1618 len = snprintf(buf, sizeof(buf),
1619 "unknown format, %s skipped in %s\n",
1620 sizefmt(s1buf, sizeof(s1buf), rdcnt),
1621 timefmt(tbuf, sizeof(tbuf), rdcnt, secs));
1622 if (n == 0)
1623 (void)fprintf(outf, "%s: %s", argv0, buf);
1624 else
1625 (void)write(STDERR_FILENO, buf, len);
1626 return;
1627 }
1628
1629
1630 if (n != 0) {
1631 len = snprintf(buf, sizeof(buf), "Working on `%s' (%s)\n",
1632 archd.name, sizefmt(s1buf, sizeof(s1buf), archd.sb.st_size));
1633 (void)write(STDERR_FILENO, buf, len);
1634 }
1635
1636
1637 len = snprintf(buf, sizeof(buf),
1638 "%s vol %d, %lu files, %s read, %s written in %s\n",
1639 frmt->name, arvol-1, (unsigned long)flcnt,
1640 sizefmt(s1buf, sizeof(s1buf), rdcnt),
1641 sizefmt(s2buf, sizeof(s2buf), wrcnt),
1642 timefmt(tbuf, sizeof(tbuf), rdcnt + wrcnt, secs));
1643 if (n == 0)
1644 (void)fprintf(outf, "%s: %s", argv0, buf);
1645 else
1646 (void)write(STDERR_FILENO, buf, strlen(buf));
1647 }
1648
1649 /*
1650 * ar_dochdir(name)
1651 * change directory to name, and remember where we came from and
1652 * where we change to (for ar_open).
1653 *
1654 * Maybe we could try to be smart and only do the actual chdir
1655 * when necessary to write a file read from the archive, but this
1656 * is not easy to get right given the pax code structure.
1657 *
1658 * Be sure to not leak descriptors!
1659 *
1660 * We are called N * M times when extracting, and N times when
1661 * writing archives, where
1662 * N: number of -C options
1663 * M: number of files in archive
1664 *
1665 * Returns 0 if all went well, else -1.
1666 */
1667
1668 int
1669 ar_dochdir(char *name)
1670 {
1671 /* First fchdir() back... */
1672 if (fchdir(cwdfd) < 0) {
1673 syswarn(1, errno, "Can't fchdir to starting directory");
1674 return(-1);
1675 }
1676 if (chdir(name) < 0) {
1677 syswarn(1, errno, "Can't chdir to %s", name);
1678 return(-1);
1679 }
1680 return (0);
1681 }
1682