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