ar_io.c revision 1.4 1 /* $NetBSD: ar_io.c,v 1.4 1995/03/21 09:07:04 cgd 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 #ifndef lint
41 #if 0
42 static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94";
43 #else
44 static char rcsid[] = "$NetBSD: ar_io.c,v 1.4 1995/03/21 09:07:04 cgd Exp $";
45 #endif
46 #endif /* not lint */
47
48 #include <sys/types.h>
49 #include <sys/time.h>
50 #include <sys/stat.h>
51 #include <sys/ioctl.h>
52 #include <sys/mtio.h>
53 #include <sys/param.h>
54 #include <signal.h>
55 #include <string.h>
56 #include <fcntl.h>
57 #include <unistd.h>
58 #include <stdio.h>
59 #include <ctype.h>
60 #include <errno.h>
61 #include <stdlib.h>
62 #include "pax.h"
63 #include "extern.h"
64
65 /*
66 * Routines which deal directly with the archive I/O device/file.
67 */
68
69 #define DMOD 0666 /* default mode of created archives */
70 #define EXT_MODE O_RDONLY /* open mode for list/extract */
71 #define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */
72 #define APP_MODE O_RDWR /* mode for append */
73 #define STDO "<STDOUT>" /* psuedo name for stdout */
74 #define STDN "<STDIN>" /* psuedo name for stdin */
75 static int arfd = -1; /* archive file descriptor */
76 static int artyp = ISREG; /* archive type: file/FIFO/tape */
77 static int arvol = 1; /* archive volume number */
78 static int lstrval = -1; /* return value from last i/o */
79 static int io_ok; /* i/o worked on volume after resync */
80 static int did_io; /* did i/o ever occur on volume? */
81 static int done; /* set via tty termination */
82 static struct stat arsb; /* stat of archive device at open */
83 static int invld_rec; /* tape has out of spec record size */
84 static int wr_trail = 1; /* trailer was rewritten in append */
85 static int can_unlnk = 0; /* do we unlink null archives? */
86 char *arcname; /* printable name of archive */
87
88 static int get_phys __P((void));
89 extern sigset_t s_mask;
90
91 /*
92 * ar_open()
93 * Opens the next archive volume. Determines the type of the device and
94 * sets up block sizes as required by the archive device and the format.
95 * Note: we may be called with name == NULL on the first open only.
96 * Return:
97 * -1 on failure, 0 otherwise
98 */
99
100 #if __STDC__
101 int
102 ar_open(char *name)
103 #else
104 int
105 ar_open(name)
106 char *name;
107 #endif
108 {
109 struct mtget mb;
110
111 if (arfd != -1)
112 (void)close(arfd);
113 arfd = -1;
114 can_unlnk = did_io = io_ok = invld_rec = 0;
115 artyp = ISREG;
116 flcnt = 0;
117
118 /*
119 * open based on overall operation mode
120 */
121 switch (act) {
122 case LIST:
123 case EXTRACT:
124 if (name == NULL) {
125 arfd = STDIN_FILENO;
126 arcname = STDN;
127 } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
128 syswarn(0, errno, "Failed open to read on %s", name);
129 break;
130 case ARCHIVE:
131 if (name == NULL) {
132 arfd = STDOUT_FILENO;
133 arcname = STDO;
134 } else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
135 syswarn(0, errno, "Failed open to write on %s", name);
136 else
137 can_unlnk = 1;
138 break;
139 case APPND:
140 if (name == NULL) {
141 arfd = STDOUT_FILENO;
142 arcname = STDO;
143 } else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
144 syswarn(0, errno, "Failed open to read/write on %s",
145 name);
146 break;
147 case COPY:
148 /*
149 * arfd not used in COPY mode
150 */
151 arcname = "<NONE>";
152 lstrval = 1;
153 return(0);
154 }
155 if (arfd < 0)
156 return(-1);
157
158 /*
159 * set up is based on device type
160 */
161 if (fstat(arfd, &arsb) < 0) {
162 syswarn(0, errno, "Failed stat on %s", arcname);
163 (void)close(arfd);
164 arfd = -1;
165 can_unlnk = 0;
166 return(-1);
167 }
168 if (S_ISDIR(arsb.st_mode)) {
169 warn(0, "Cannot write an archive on top of a directory %s",
170 arcname);
171 (void)close(arfd);
172 arfd = -1;
173 can_unlnk = 0;
174 return(-1);
175 }
176
177 if (S_ISCHR(arsb.st_mode))
178 artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
179 else if (S_ISBLK(arsb.st_mode))
180 artyp = ISBLK;
181 else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
182 artyp = ISPIPE;
183 else
184 artyp = ISREG;
185
186 /*
187 * make sure we beyond any doubt that we only can unlink regular files
188 * we created
189 */
190 if (artyp != ISREG)
191 can_unlnk = 0;
192 /*
193 * if we are writing, we are done
194 */
195 if (act == ARCHIVE) {
196 blksz = rdblksz = wrblksz;
197 lstrval = 1;
198 return(0);
199 }
200
201 /*
202 * set default blksz on read. APPNDs writes rdblksz on the last volume
203 * On all new archive volumes, we shift to wrblksz (if the user
204 * specified one, otherwize we will continue to use rdblksz). We
205 * must to set blocksize based on what kind of device the archive is
206 * stored.
207 */
208 switch(artyp) {
209 case ISTAPE:
210 /*
211 * Tape drives come in at least two flavors. Those that support
212 * variable sized records and those that have fixed sized
213 * records. They must be treated differently. For tape drives
214 * that support variable sized records, we must make large
215 * reads to make sure we get the entire record, otherwise we
216 * will just get the first part of the record (up to size we
217 * asked). Tapes with fixed sized records may or may not return
218 * multiple records in a single read. We really do not care
219 * what the physical record size is UNLESS we are going to
220 * append. (We will need the physical block size to rewrite
221 * the trailer). Only when we are appending do we go to the
222 * effort to figure out the true PHYSICAL record size.
223 */
224 blksz = rdblksz = MAXBLK;
225 break;
226 case ISPIPE:
227 case ISBLK:
228 case ISCHR:
229 /*
230 * Blocksize is not a major issue with these devices (but must
231 * be kept a multiple of 512). If the user specified a write
232 * block size, we use that to read. Under append, we must
233 * always keep blksz == rdblksz. Otherwise we go ahead and use
234 * the device optimal blocksize as (and if) returned by stat
235 * and if it is within pax specs.
236 */
237 if ((act == APPND) && wrblksz) {
238 blksz = rdblksz = wrblksz;
239 break;
240 }
241
242 if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
243 ((arsb.st_blksize % BLKMULT) == 0))
244 rdblksz = arsb.st_blksize;
245 else
246 rdblksz = DEVBLK;
247 /*
248 * For performance go for large reads when we can without harm
249 */
250 if ((act == APPND) || (artyp == ISCHR))
251 blksz = rdblksz;
252 else
253 blksz = MAXBLK;
254 break;
255 case ISREG:
256 /*
257 * if the user specified wrblksz works, use it. Under appends
258 * we must always keep blksz == rdblksz
259 */
260 if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
261 blksz = rdblksz = wrblksz;
262 break;
263 }
264 /*
265 * See if we can find the blocking factor from the file size
266 */
267 for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
268 if ((arsb.st_size % rdblksz) == 0)
269 break;
270 /*
271 * When we cannont find a match, we may have a flawed archive.
272 */
273 if (rdblksz <= 0)
274 rdblksz = FILEBLK;
275 /*
276 * for performance go for large reads when we can
277 */
278 if (act == APPND)
279 blksz = rdblksz;
280 else
281 blksz = MAXBLK;
282 break;
283 default:
284 /*
285 * should never happen, worse case, slow...
286 */
287 blksz = rdblksz = BLKMULT;
288 break;
289 }
290 lstrval = 1;
291 return(0);
292 }
293
294 /*
295 * ar_close()
296 * closes archive device, increments volume number, and prints i/o summary
297 */
298 #if __STDC__
299 void
300 ar_close(void)
301 #else
302 void
303 ar_close()
304 #endif
305 {
306 FILE *outf;
307
308 if (arfd < 0) {
309 did_io = io_ok = flcnt = 0;
310 return;
311 }
312
313 if (act == LIST)
314 outf = stdout;
315 else
316 outf = stderr;
317
318 /*
319 * Close archive file. This may take a LONG while on tapes (we may be
320 * forced to wait for the rewind to complete) so tell the user what is
321 * going on (this avoids the user hitting control-c thinking pax is
322 * broken).
323 */
324 if (vflag && (artyp == ISTAPE)) {
325 if (vfpart)
326 (void)putc('\n', outf);
327 (void)fprintf(outf,
328 "%s: Waiting for tape drive close to complete...",
329 argv0);
330 (void)fflush(outf);
331 }
332
333 /*
334 * if nothing was written to the archive (and we created it), we remove
335 * it
336 */
337 if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
338 (arsb.st_size == 0)) {
339 (void)unlink(arcname);
340 can_unlnk = 0;
341 }
342
343 (void)close(arfd);
344
345 if (vflag && (artyp == ISTAPE)) {
346 (void)fputs("done.\n", outf);
347 vfpart = 0;
348 (void)fflush(outf);
349 }
350 arfd = -1;
351
352 if (!io_ok && !did_io) {
353 flcnt = 0;
354 return;
355 }
356 did_io = io_ok = 0;
357
358 /*
359 * The volume number is only increased when the last device has data
360 * and we have already determined the archive format.
361 */
362 if (frmt != NULL)
363 ++arvol;
364
365 if (!vflag) {
366 flcnt = 0;
367 return;
368 }
369
370 /*
371 * Print out a summary of I/O for this archive volume.
372 */
373 if (vfpart) {
374 (void)putc('\n', outf);
375 vfpart = 0;
376 }
377
378 /*
379 * If we have not determined the format yet, we just say how many bytes
380 * we have skipped over looking for a header to id. there is no way we
381 * could have written anything yet.
382 */
383 if (frmt == NULL) {
384 # ifdef NET2_STAT
385 (void)fprintf(outf, "%s: unknown format, %lu bytes skipped.\n",
386 # else
387 (void)fprintf(outf, "%s: unknown format, %qu bytes skipped.\n",
388 # endif
389 argv0, rdcnt);
390 (void)fflush(outf);
391 flcnt = 0;
392 return;
393 }
394
395 (void)fprintf(outf,
396 # ifdef NET2_STAT
397 "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
398 # else
399 "%s: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n",
400 # endif
401 argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
402 (void)fflush(outf);
403 flcnt = 0;
404 }
405
406 /*
407 * ar_drain()
408 * drain any archive format independent padding from an archive read
409 * from a socket or a pipe. This is to prevent the process on the
410 * other side of the pipe from getting a SIGPIPE (pax will stop
411 * reading an archive once a format dependent trailer is detected).
412 */
413 #if __STDC__
414 void
415 ar_drain(void)
416 #else
417 void
418 ar_drain()
419 #endif
420 {
421 register int res;
422 char drbuf[MAXBLK];
423
424 /*
425 * we only drain from a pipe/socket. Other devices can be closed
426 * without reading up to end of file. We sure hope that pipe is closed
427 * on the other side so we will get an EOF.
428 */
429 if ((artyp != ISPIPE) || (lstrval <= 0))
430 return;
431
432 /*
433 * keep reading until pipe is drained
434 */
435 while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
436 ;
437 lstrval = res;
438 }
439
440 /*
441 * ar_set_wr()
442 * Set up device right before switching from read to write in an append.
443 * device dependent code (if required) to do this should be added here.
444 * For all archive devices we are already positioned at the place we want
445 * to start writing when this routine is called.
446 * Return:
447 * 0 if all ready to write, -1 otherwise
448 */
449
450 #if __STDC__
451 int
452 ar_set_wr(void)
453 #else
454 int
455 ar_set_wr()
456 #endif
457 {
458 off_t cpos;
459
460 /*
461 * we must make sure the trailer is rewritten on append, ar_next()
462 * will stop us if the archive containing the trailer was not written
463 */
464 wr_trail = 0;
465
466 /*
467 * Add any device dependent code as required here
468 */
469 if (artyp != ISREG)
470 return(0);
471 /*
472 * Ok we have an archive in a regular file. If we were rewriting a
473 * file, we must get rid of all the stuff after the current offset
474 * (it was not written by pax).
475 */
476 if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
477 (ftruncate(arfd, cpos) < 0)) {
478 syswarn(1, errno, "Unable to truncate archive file");
479 return(-1);
480 }
481 return(0);
482 }
483
484 /*
485 * ar_app_ok()
486 * check if the last volume in the archive allows appends. We cannot check
487 * this until we are ready to write since there is no spec that says all
488 * volumes in a single archive have to be of the same type...
489 * Return:
490 * 0 if we can append, -1 otherwise.
491 */
492
493 #if __STDC__
494 int
495 ar_app_ok(void)
496 #else
497 int
498 ar_app_ok()
499 #endif
500 {
501 if (artyp == ISPIPE) {
502 warn(1, "Cannot append to an archive obtained from a pipe.");
503 return(-1);
504 }
505
506 if (!invld_rec)
507 return(0);
508 warn(1,"Cannot append, device record size %d does not support %s spec",
509 rdblksz, argv0);
510 return(-1);
511 }
512
513 /*
514 * ar_read()
515 * read up to a specified number of bytes from the archive into the
516 * supplied buffer. When dealing with tapes we may not always be able to
517 * read what we want.
518 * Return:
519 * Number of bytes in buffer. 0 for end of file, -1 for a read error.
520 */
521
522 #if __STDC__
523 int
524 ar_read(register char *buf, register int cnt)
525 #else
526 int
527 ar_read(buf, cnt)
528 register char *buf;
529 register int cnt;
530 #endif
531 {
532 register int res = 0;
533
534 /*
535 * if last i/o was in error, no more reads until reset or new volume
536 */
537 if (lstrval <= 0)
538 return(lstrval);
539
540 /*
541 * how we read must be based on device type
542 */
543 switch (artyp) {
544 case ISTAPE:
545 if ((res = read(arfd, buf, cnt)) > 0) {
546 /*
547 * CAUTION: tape systems may not always return the same
548 * sized records so we leave blksz == MAXBLK. The
549 * physical record size that a tape drive supports is
550 * very hard to determine in a uniform and portable
551 * manner.
552 */
553 io_ok = 1;
554 if (res != rdblksz) {
555 /*
556 * Record size changed. If this is happens on
557 * any record after the first, we probably have
558 * a tape drive which has a fixed record size
559 * we are getting multiple records in a single
560 * read). Watch out for record blocking that
561 * violates pax spec (must be a multiple of
562 * BLKMULT).
563 */
564 rdblksz = res;
565 if (rdblksz % BLKMULT)
566 invld_rec = 1;
567 }
568 return(res);
569 }
570 break;
571 case ISREG:
572 case ISBLK:
573 case ISCHR:
574 case ISPIPE:
575 default:
576 /*
577 * Files are so easy to deal with. These other things cannot
578 * be trusted at all. So when we are dealing with character
579 * devices and pipes we just take what they have ready for us
580 * and return. Trying to do anything else with them runs the
581 * risk of failure.
582 */
583 if ((res = read(arfd, buf, cnt)) > 0) {
584 io_ok = 1;
585 return(res);
586 }
587 break;
588 }
589
590 /*
591 * We are in trouble at this point, something is broken...
592 */
593 lstrval = res;
594 if (res < 0)
595 syswarn(1, errno, "Failed read on archive volume %d", arvol);
596 else
597 warn(0, "End of archive volume %d reached", arvol);
598 return(res);
599 }
600
601 /*
602 * ar_write()
603 * Write a specified number of bytes in supplied buffer to the archive
604 * device so it appears as a single "block". Deals with errors and tries
605 * to recover when faced with short writes.
606 * Return:
607 * Number of bytes written. 0 indicates end of volume reached and with no
608 * flaws (as best that can be detected). A -1 indicates an unrecoverable
609 * error in the archive occured.
610 */
611
612 #if __STDC__
613 int
614 ar_write(register char *buf, register int bsz)
615 #else
616 int
617 ar_write(buf, bsz)
618 register char *buf;
619 register int bsz;
620 #endif
621 {
622 register int res;
623 off_t cpos;
624
625 /*
626 * do not allow pax to create a "bad" archive. Once a write fails on
627 * an archive volume prevent further writes to it.
628 */
629 if (lstrval <= 0)
630 return(lstrval);
631
632 if ((res = write(arfd, buf, bsz)) == bsz) {
633 wr_trail = 1;
634 io_ok = 1;
635 return(bsz);
636 }
637 /*
638 * write broke, see what we can do with it. We try to send any partial
639 * writes that may violate pax spec to the next archive volume.
640 */
641 if (res < 0)
642 lstrval = res;
643 else
644 lstrval = 0;
645
646 switch (artyp) {
647 case ISREG:
648 if ((res > 0) && (res % BLKMULT)) {
649 /*
650 * try to fix up partial writes which are not BLKMULT
651 * in size by forcing the runt record to next archive
652 * volume
653 */
654 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
655 break;
656 cpos -= (off_t)res;
657 if (ftruncate(arfd, cpos) < 0)
658 break;
659 res = lstrval = 0;
660 break;
661 }
662 if (res >= 0)
663 break;
664 /*
665 * if file is out of space, handle it like a return of 0
666 */
667 if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))
668 res = lstrval = 0;
669 break;
670 case ISTAPE:
671 case ISCHR:
672 case ISBLK:
673 if (res >= 0)
674 break;
675 if (errno == EACCES) {
676 warn(0, "Write failed, archive is write protected.");
677 res = lstrval = 0;
678 return(0);
679 }
680 /*
681 * see if we reached the end of media, if so force a change to
682 * the next volume
683 */
684 if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
685 res = lstrval = 0;
686 break;
687 case ISPIPE:
688 default:
689 /*
690 * we cannot fix errors to these devices
691 */
692 break;
693 }
694
695 /*
696 * Better tell the user the bad news...
697 * if this is a block aligned archive format, we may have a bad archive
698 * if the format wants the header to start at a BLKMULT boundry. While
699 * we can deal with the mis-aligned data, it violates spec and other
700 * archive readers will likely fail. if the format is not block
701 * aligned, the user may be lucky (and the archive is ok).
702 */
703 if (res >= 0) {
704 if (res > 0)
705 wr_trail = 1;
706 io_ok = 1;
707 }
708
709 /*
710 * If we were trying to rewrite the trailer and it didn't work, we
711 * must quit right away.
712 */
713 if (!wr_trail && (res <= 0)) {
714 warn(1,"Unable to append, trailer re-write failed. Quitting.");
715 return(res);
716 }
717
718 if (res == 0)
719 warn(0, "End of archive volume %d reached", arvol);
720 else if (res < 0)
721 syswarn(1, errno, "Failed write to archive volume: %d", arvol);
722 else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
723 warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");
724 else
725 warn(1,"WARNING: partial archive write. Archive IS FLAWED");
726 return(res);
727 }
728
729 /*
730 * ar_rdsync()
731 * Try to move past a bad spot on a flawed archive as needed to continue
732 * I/O. Clears error flags to allow I/O to continue.
733 * Return:
734 * 0 when ok to try i/o again, -1 otherwise.
735 */
736
737 #if __STDC__
738 int
739 ar_rdsync(void)
740 #else
741 int
742 ar_rdsync()
743 #endif
744 {
745 long fsbz;
746 off_t cpos;
747 off_t mpos;
748 struct mtop mb;
749
750 /*
751 * Fail resync attempts at user request (done) or this is going to be
752 * an update/append to a existing archive. if last i/o hit media end,
753 * we need to go to the next volume not try a resync
754 */
755 if ((done > 0) || (lstrval == 0))
756 return(-1);
757
758 if ((act == APPND) || (act == ARCHIVE)) {
759 warn(1, "Cannot allow updates to an archive with flaws.");
760 return(-1);
761 }
762 if (io_ok)
763 did_io = 1;
764
765 switch(artyp) {
766 case ISTAPE:
767 /*
768 * if the last i/o was a successful data transfer, we assume
769 * the fault is just a bad record on the tape that we are now
770 * past. If we did not get any data since the last resync try
771 * to move the tape foward one PHYSICAL record past any
772 * damaged tape section. Some tape drives are stubborn and need
773 * to be pushed.
774 */
775 if (io_ok) {
776 io_ok = 0;
777 lstrval = 1;
778 break;
779 }
780 mb.mt_op = MTFSR;
781 mb.mt_count = 1;
782 if (ioctl(arfd, MTIOCTOP, &mb) < 0)
783 break;
784 lstrval = 1;
785 break;
786 case ISREG:
787 case ISCHR:
788 case ISBLK:
789 /*
790 * try to step over the bad part of the device.
791 */
792 io_ok = 0;
793 if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
794 fsbz = BLKMULT;
795 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
796 break;
797 mpos = fsbz - (cpos % (off_t)fsbz);
798 if (lseek(arfd, mpos, SEEK_CUR) < 0)
799 break;
800 lstrval = 1;
801 break;
802 case ISPIPE:
803 default:
804 /*
805 * cannot recover on these archive device types
806 */
807 io_ok = 0;
808 break;
809 }
810 if (lstrval <= 0) {
811 warn(1, "Unable to recover from an archive read failure.");
812 return(-1);
813 }
814 warn(0, "Attempting to recover from an archive read failure.");
815 return(0);
816 }
817
818 /*
819 * ar_fow()
820 * Move the I/O position within the archive foward the specified number of
821 * bytes as supported by the device. If we cannot move the requested
822 * number of bytes, return the actual number of bytes moved in skipped.
823 * Return:
824 * 0 if moved the requested distance, -1 on complete failure, 1 on
825 * partial move (the amount moved is in skipped)
826 */
827
828 #if __STDC__
829 int
830 ar_fow(off_t sksz, off_t *skipped)
831 #else
832 int
833 ar_fow(sksz, skipped)
834 off_t sksz;
835 off_t *skipped;
836 #endif
837 {
838 off_t cpos;
839 off_t mpos;
840
841 *skipped = 0;
842 if (sksz <= 0)
843 return(0);
844
845 /*
846 * we cannot move foward at EOF or error
847 */
848 if (lstrval <= 0)
849 return(lstrval);
850
851 /*
852 * Safer to read forward on devices where it is hard to find the end of
853 * the media without reading to it. With tapes we cannot be sure of the
854 * number of physical blocks to skip (we do not know physical block
855 * size at this point), so we must only read foward on tapes!
856 */
857 if (artyp != ISREG)
858 return(0);
859
860 /*
861 * figure out where we are in the archive
862 */
863 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
864 /*
865 * we can be asked to move farther than there are bytes in this
866 * volume, if so, just go to file end and let normal buf_fill()
867 * deal with the end of file (it will go to next volume by
868 * itself)
869 */
870 if ((mpos = cpos + sksz) > arsb.st_size) {
871 *skipped = arsb.st_size - cpos;
872 mpos = arsb.st_size;
873 } else
874 *skipped = sksz;
875 if (lseek(arfd, mpos, SEEK_SET) >= 0)
876 return(0);
877 }
878 syswarn(1, errno, "Foward positioning operation on archive failed");
879 lstrval = -1;
880 return(-1);
881 }
882
883 /*
884 * ar_rev()
885 * move the i/o position within the archive backwards the specified byte
886 * count as supported by the device. With tapes drives we RESET rdblksz to
887 * the PHYSICAL blocksize.
888 * NOTE: We should only be called to move backwards so we can rewrite the
889 * last records (the trailer) of an archive (APPEND).
890 * Return:
891 * 0 if moved the requested distance, -1 on complete failure
892 */
893
894 #if __STDC__
895 int
896 ar_rev(off_t sksz)
897 #else
898 int
899 ar_rev(sksz)
900 off_t sksz;
901 #endif
902 {
903 off_t cpos;
904 struct mtop mb;
905 register int phyblk;
906
907 /*
908 * make sure we do not have try to reverse on a flawed archive
909 */
910 if (lstrval < 0)
911 return(lstrval);
912
913 switch(artyp) {
914 case ISPIPE:
915 if (sksz <= 0)
916 break;
917 /*
918 * cannot go backwards on these critters
919 */
920 warn(1, "Reverse positioning on pipes is not supported.");
921 lstrval = -1;
922 return(-1);
923 case ISREG:
924 case ISBLK:
925 case ISCHR:
926 default:
927 if (sksz <= 0)
928 break;
929
930 /*
931 * For things other than files, backwards movement has a very
932 * high probability of failure as we really do not know the
933 * true attributes of the device we are talking to (the device
934 * may not even have the ability to lseek() in any direction).
935 * First we figure out where we are in the archive.
936 */
937 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
938 syswarn(1, errno,
939 "Unable to obtain current archive byte offset");
940 lstrval = -1;
941 return(-1);
942 }
943
944 /*
945 * we may try to go backwards past the start when the archive
946 * is only a single record. If this hapens and we are on a
947 * multi volume archive, we need to go to the end of the
948 * previous volume and continue our movement backwards from
949 * there.
950 */
951 if ((cpos -= sksz) < (off_t)0L) {
952 if (arvol > 1) {
953 /*
954 * this should never happen
955 */
956 warn(1,"Reverse position on previous volume.");
957 lstrval = -1;
958 return(-1);
959 }
960 cpos = (off_t)0L;
961 }
962 if (lseek(arfd, cpos, SEEK_SET) < 0) {
963 syswarn(1, errno, "Unable to seek archive backwards");
964 lstrval = -1;
965 return(-1);
966 }
967 break;
968 case ISTAPE:
969 /*
970 * Calculate and move the proper number of PHYSICAL tape
971 * blocks. If the sksz is not an even multiple of the physical
972 * tape size, we cannot do the move (this should never happen).
973 * (We also cannot handler trailers spread over two vols).
974 * get_phys() also makes sure we are in front of the filemark.
975 */
976 if ((phyblk = get_phys()) <= 0) {
977 lstrval = -1;
978 return(-1);
979 }
980
981 /*
982 * make sure future tape reads only go by physical tape block
983 * size (set rdblksz to the real size).
984 */
985 rdblksz = phyblk;
986
987 /*
988 * if no movement is required, just return (we must be after
989 * get_phys() so the physical blocksize is properly set)
990 */
991 if (sksz <= 0)
992 break;
993
994 /*
995 * ok we have to move. Make sure the tape drive can do it.
996 */
997 if (sksz % phyblk) {
998 warn(1,
999 "Tape drive unable to backspace requested amount");
1000 lstrval = -1;
1001 return(-1);
1002 }
1003
1004 /*
1005 * move backwards the requested number of bytes
1006 */
1007 mb.mt_op = MTBSR;
1008 mb.mt_count = sksz/phyblk;
1009 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1010 syswarn(1,errno, "Unable to backspace tape %d blocks.",
1011 mb.mt_count);
1012 lstrval = -1;
1013 return(-1);
1014 }
1015 break;
1016 }
1017 lstrval = 1;
1018 return(0);
1019 }
1020
1021 /*
1022 * get_phys()
1023 * Determine the physical block size on a tape drive. We need the physical
1024 * block size so we know how many bytes we skip over when we move with
1025 * mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when
1026 * return.
1027 * This is one really SLOW routine...
1028 * Return:
1029 * physical block size if ok (ok > 0), -1 otherwise
1030 */
1031
1032 #if __STDC__
1033 static int
1034 get_phys(void)
1035 #else
1036 static int
1037 get_phys()
1038 #endif
1039 {
1040 register int padsz = 0;
1041 register int res;
1042 register int phyblk;
1043 struct mtop mb;
1044 char scbuf[MAXBLK];
1045
1046 /*
1047 * move to the file mark, and then back up one record and read it.
1048 * this should tell us the physical record size the tape is using.
1049 */
1050 if (lstrval == 1) {
1051 /*
1052 * we know we are at file mark when we get back a 0 from
1053 * read()
1054 */
1055 while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
1056 padsz += res;
1057 if (res < 0) {
1058 syswarn(1, errno, "Unable to locate tape filemark.");
1059 return(-1);
1060 }
1061 }
1062
1063 /*
1064 * move backwards over the file mark so we are at the end of the
1065 * last record.
1066 */
1067 mb.mt_op = MTBSF;
1068 mb.mt_count = 1;
1069 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1070 syswarn(1, errno, "Unable to backspace over tape filemark.");
1071 return(-1);
1072 }
1073
1074 /*
1075 * move backwards so we are in front of the last record and read it to
1076 * get physical tape blocksize.
1077 */
1078 mb.mt_op = MTBSR;
1079 mb.mt_count = 1;
1080 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1081 syswarn(1, errno, "Unable to backspace over last tape block.");
1082 return(-1);
1083 }
1084 if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
1085 syswarn(1, errno, "Cannot determine archive tape blocksize.");
1086 return(-1);
1087 }
1088
1089 /*
1090 * read foward to the file mark, then back up in front of the filemark
1091 * (this is a bit paranoid, but should be safe to do).
1092 */
1093 while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
1094 ;
1095 if (res < 0) {
1096 syswarn(1, errno, "Unable to locate tape filemark.");
1097 return(-1);
1098 }
1099 mb.mt_op = MTBSF;
1100 mb.mt_count = 1;
1101 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1102 syswarn(1, errno, "Unable to backspace over tape filemark.");
1103 return(-1);
1104 }
1105
1106 /*
1107 * set lstrval so we know that the filemark has not been seen
1108 */
1109 lstrval = 1;
1110
1111 /*
1112 * return if there was no padding
1113 */
1114 if (padsz == 0)
1115 return(phyblk);
1116
1117 /*
1118 * make sure we can move backwards over the padding. (this should
1119 * never fail).
1120 */
1121 if (padsz % phyblk) {
1122 warn(1, "Tape drive unable to backspace requested amount");
1123 return(-1);
1124 }
1125
1126 /*
1127 * move backwards over the padding so the head is where it was when
1128 * we were first called (if required).
1129 */
1130 mb.mt_op = MTBSR;
1131 mb.mt_count = padsz/phyblk;
1132 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
1133 syswarn(1,errno,"Unable to backspace tape over %d pad blocks",
1134 mb.mt_count);
1135 return(-1);
1136 }
1137 return(phyblk);
1138 }
1139
1140 /*
1141 * ar_next()
1142 * prompts the user for the next volume in this archive. For some devices
1143 * we may allow the media to be changed. Otherwise a new archive is
1144 * prompted for. By pax spec, if there is no controlling tty or an eof is
1145 * read on tty input, we must quit pax.
1146 * Return:
1147 * 0 when ready to continue, -1 when all done
1148 */
1149
1150 #if __STDC__
1151 int
1152 ar_next(void)
1153 #else
1154 int
1155 ar_next()
1156 #endif
1157 {
1158 char buf[PAXPATHLEN+2];
1159 static int freeit = 0;
1160 sigset_t o_mask;
1161
1162 /*
1163 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so
1164 * things like writing EOF etc will be done) (Watch out ar_close() can
1165 * also be called via a signal handler, so we must prevent a race.
1166 */
1167 if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
1168 syswarn(0, errno, "Unable to set signal mask");
1169 ar_close();
1170 if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0)
1171 syswarn(0, errno, "Unable to restore signal mask");
1172
1173 if (done || !wr_trail)
1174 return(-1);
1175
1176 tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
1177
1178 /*
1179 * if i/o is on stdin or stdout, we cannot reopen it (we do not know
1180 * the name), the user will be forced to type it in.
1181 */
1182 if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG)
1183 && (artyp != ISPIPE)) {
1184 if (artyp == ISTAPE) {
1185 tty_prnt("%s ready for archive tape volume: %d\n",
1186 arcname, arvol);
1187 tty_prnt("Load the NEXT TAPE on the tape drive");
1188 } else {
1189 tty_prnt("%s ready for archive volume: %d\n",
1190 arcname, arvol);
1191 tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
1192 }
1193
1194 if ((act == ARCHIVE) || (act == APPND))
1195 tty_prnt(" and make sure it is WRITE ENABLED.\n");
1196 else
1197 tty_prnt("\n");
1198
1199 for(;;) {
1200 tty_prnt("Type \"y\" to continue, \".\" to quit %s,",
1201 argv0);
1202 tty_prnt(" or \"s\" to switch to new device.\nIf you");
1203 tty_prnt(" cannot change storage media, type \"s\"\n");
1204 tty_prnt("Is the device ready and online? > ");
1205
1206 if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
1207 done = 1;
1208 lstrval = -1;
1209 tty_prnt("Quitting %s!\n", argv0);
1210 vfpart = 0;
1211 return(-1);
1212 }
1213
1214 if ((buf[0] == '\0') || (buf[1] != '\0')) {
1215 tty_prnt("%s unknown command, try again\n",buf);
1216 continue;
1217 }
1218
1219 switch (buf[0]) {
1220 case 'y':
1221 case 'Y':
1222 /*
1223 * we are to continue with the same device
1224 */
1225 if (ar_open(arcname) >= 0)
1226 return(0);
1227 tty_prnt("Cannot re-open %s, try again\n",
1228 arcname);
1229 continue;
1230 case 's':
1231 case 'S':
1232 /*
1233 * user wants to open a different device
1234 */
1235 tty_prnt("Switching to a different archive\n");
1236 break;
1237 default:
1238 tty_prnt("%s unknown command, try again\n",buf);
1239 continue;
1240 }
1241 break;
1242 }
1243 } else
1244 tty_prnt("Ready for archive volume: %d\n", arvol);
1245
1246 /*
1247 * have to go to a different archive
1248 */
1249 for (;;) {
1250 tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);
1251 tty_prnt("Archive name > ");
1252
1253 if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
1254 done = 1;
1255 lstrval = -1;
1256 tty_prnt("Quitting %s!\n", argv0);
1257 vfpart = 0;
1258 return(-1);
1259 }
1260 if (buf[0] == '\0') {
1261 tty_prnt("Empty file name, try again\n");
1262 continue;
1263 }
1264 if (!strcmp(buf, "..")) {
1265 tty_prnt("Illegal file name: .. try again\n");
1266 continue;
1267 }
1268 if (strlen(buf) > PAXPATHLEN) {
1269 tty_prnt("File name too long, try again\n");
1270 continue;
1271 }
1272
1273 /*
1274 * try to open new archive
1275 */
1276 if (ar_open(buf) >= 0) {
1277 if (freeit) {
1278 (void)free(arcname);
1279 freeit = 0;
1280 }
1281 if ((arcname = strdup(buf)) == NULL) {
1282 done = 1;
1283 lstrval = -1;
1284 warn(0, "Cannot save archive name.");
1285 return(-1);
1286 }
1287 freeit = 1;
1288 break;
1289 }
1290 tty_prnt("Cannot open %s, try again\n", buf);
1291 continue;
1292 }
1293 return(0);
1294 }
1295