Lines Matching +full:write +full:- +full:to +full:- +full:read

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
8 * This code is derived from software contributed to Berkeley by
20 * may be used to endorse or promote products derived from this software
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 #define MAXFLT 10 /* default media read error limit */
53 * Need to change bufmem to dynamic allocation when the upper
55 * MAXBLK define and tests will also need to be updated.
60 static char *bufpt; /* read/write point in i/o buffer */
64 int rdblksz; /* first read blksize (tapes only) */
67 off_t rdcnt; /* # of bytes read on current vol */
71 * set up the buffering system to operate in a write mode
73 * 0 if ok, -1 if the user specified write block size violates pax spec
81 * Check to make sure the write block size meets pax specs. If the user in wr_start()
83 * We must be picky on writes, so we do not allow the user to create an in wr_start()
84 * archive that might be hard to read elsewhere. If all ok, we then in wr_start()
88 wrblksz = frmt->bsz; in wr_start()
90 paxwarn(1, "Write block size of %d too large, maximum is: %d", in wr_start()
92 return(-1); in wr_start()
95 paxwarn(1, "Write block size of %d is not a %d byte multiple", in wr_start()
97 return(-1); in wr_start()
100 paxwarn(0, "Write block size of %d larger than POSIX max %d, archive may not be portable", in wr_start()
102 return(-1); in wr_start()
106 * we only allow wrblksz to be used with all archive operations in wr_start()
110 return(-1); in wr_start()
119 * set up buffering system to read an archive
121 * 0 if ok, -1 otherwise
129 * going to append and user specified a write block size, check it in rd_start()
135 paxwarn(1,"Write block size %d too large, maximum is: %d", in rd_start()
137 return(-1); in rd_start()
140 paxwarn(1, "Write block size %d is not a %d byte multiple", in rd_start()
142 return(-1); in rd_start()
150 return(-1); in rd_start()
171 * Set up the buffering system to append new members to an archive that
172 * was just read. The last block(s) of an archive may contain a format
173 * specific trailer. To append a new member, this trailer has to be
175 * the start of the header of the first file added to the archive. The
176 * format specific end read function tells us how many bytes to move
177 * backwards in the archive to be positioned BEFORE the trailer. Two
178 * different positions have to be adjusted, the O.S. file offset (e.g. the
179 * position of the tape head) and the write point within the data we have
180 * stored in the read (soon to become write) buffer. We may have to move
182 * record and the size of the format trailer) to read up the record where
186 * move the OS file offset back to the start of this record and read it
187 * up. We set the buffer write pointer to be at this byte (the byte where
188 * the trailer starts). We then move the OS file pointer back to the
193 * about the conditions under which they will allow a write to occur.
195 * so it may not be feasible to append archives stored on all types of
198 * 0 for success, -1 for failure
208 paxwarn(0, "Cannot append to an archive that may have flaws."); in appnd_start()
209 return(-1); in appnd_start()
212 * if the user did not specify a write blocksize, inherit the size used in appnd_start()
213 * in the last archive volume read. (If a is set we still use rdblksz in appnd_start()
225 return(-1); in appnd_start()
228 * Calculate bytes to move back and move in front of record where we in appnd_start()
229 * need to start writing from. Remember we have to add in any padding in appnd_start()
231 * travel skcnt + padding ROUNDED UP to blksize. in appnd_start()
233 skcnt += bufend - bufpt; in appnd_start()
241 * now in front of, read up the block and position the pointer after in appnd_start()
244 if ((cnt -= skcnt) > 0) { in appnd_start()
247 * to be real physical blocksize so we must loop until we get in appnd_start()
258 if (ar_rev((off_t)(bufpt - buf)) < 0) in appnd_start()
270 rdcnt -= skcnt; in appnd_start()
274 * At this point we are ready to write. If the device requires special in appnd_start()
275 * handling to write at a point were previously recorded data resides, in appnd_start()
277 * ARCHIVE mode (write) conditions in appnd_start()
280 return(-1); in appnd_start()
285 paxwarn(1, "Unable to rewrite archive trailer, cannot append."); in appnd_start()
286 return(-1); in appnd_start()
291 * A read error occurred on this archive volume. Resync the buffer and
292 * try to reset the device (if possible) so we can continue to read. Keep
293 * trying to do this until we get a valid read, or we reach the limit on
294 * consecutive read faults (at which point we give up). The user can
295 * adjust the read error limit through a command line option.
297 * 0 on success, and -1 on failure
310 return(-1); in rd_sync()
312 paxwarn(1, "Unable to append when there are archive read errors."); in rd_sync()
313 return(-1); in rd_sync()
317 * poke at device and try to get past media error in rd_sync()
321 return(-1); in rd_sync()
338 * Oh well, yet another failed read... in rd_sync()
339 * if error limit reached, ditch. o.w. poke device to move past in rd_sync()
342 * volume. remember the goal on reads is to get the most we in rd_sync()
346 paxwarn(0,"Archive read error limit (%d) reached",maxflt); in rd_sync()
354 return(-1); in rd_sync()
361 * overlap a block boundary (as in the case we are trying to recover a
362 * flawed archived). This was not designed to be used for any other
371 bufpt -= cnt; in pback()
378 * skip forward in the archive during an archive read. Used to get quickly
381 * 0 if ok, -1 failure, and 1 when EOF on the archive volume was detected.
392 * consume what data we have in the buffer. If we have to move forward in rd_skip()
393 * whole records, we call the low level skip function to see if we can in rd_skip()
399 res = MIN((bufend - bufpt), skcnt); in rd_skip()
401 skcnt -= res; in rd_skip()
410 * We have to read more, calculate complete and partial record reads in rd_skip()
417 * if the skip fails, we will have to resync. ar_fow will tell us in rd_skip()
418 * how much it can skip over. We will have to read the rest. in rd_skip()
421 return(-1); in rd_skip()
422 res += cnt - skipped; in rd_skip()
426 * what is left we have to read (which may be the whole thing if in rd_skip()
427 * ar_fow() told us the device can only read to skip records); in rd_skip()
430 cnt = bufend - bufpt; in rd_skip()
432 * if the read fails, we will have to resync in rd_skip()
435 return(-1); in rd_skip()
440 res -= cnt; in rd_skip()
448 * with zero (even though we do not have to). Padding with 0 makes it a
449 * lot easier to recover if the archive is damaged. zero padding SHOULD
457 memset(bufpt, 0, bufend - bufpt); in wr_fin()
465 * fill the write buffer from data passed to it in a buffer (usually used
466 * by format specific write routines to pass a file header). On failure we
467 * punt. We do not allow the user to continue to write flawed archives.
471 * 0 if buffer was filled ok, -1 o.w. (buffer flush failure)
480 * while there is data to copy into the write buffer. when the in wr_rdbuf()
481 * write buffer fills, flush it to the archive and continue in wr_rdbuf()
484 cnt = bufend - bufpt; in wr_rdbuf()
486 return(-1); in wr_rdbuf()
494 outcnt -= cnt; in wr_rdbuf()
501 * copy from the read buffer into a supplied buffer a specified number of
502 * bytes. If the read buffer is empty fill it and continue to copy.
503 * usually used to obtain a file header for processing by a format
504 * specific read routine.
506 * number of bytes copied to the buffer, 0 indicates EOF on archive volume,
507 * -1 is a read error
521 cnt = bufend - bufpt; in rd_wrbuf()
524 * read error, return what we got (or the error if in rd_wrbuf()
526 * error occurred and has the best knowledge what to in rd_wrbuf()
529 if ((res = cpcnt - incnt) > 0) in rd_wrbuf()
535 * calculate how much data to copy based on what's left and in rd_wrbuf()
541 incnt -= cnt; in rd_wrbuf()
549 * skip forward during a write. In other words add padding to the file.
550 * we add zero filled padding as it makes flawed archives much easier to
551 * recover from. the caller tells us how many bytes of padding to add
552 * This routine was not designed to add HUGE amount of padding, just small
555 * 0 if ok, -1 if there was a buf_flush failure
564 * loop while there is more padding to add in wr_skip()
567 cnt = bufend - bufpt; in wr_skip()
569 return(-1); in wr_skip()
573 skcnt -= cnt; in wr_skip()
580 * fill write buffer with the contents of a file. We are passed an open
581 * file descriptor to the file and the archive structure that describes the
582 * file we are storing. The variable "left" is modified to contain the
583 * number of bytes of the file we were NOT able to write to the archive.
584 * it is important that we always write EXACTLY the number of bytes that
585 * the format specific write routine told us to. The file can also get
586 * bigger, so reading to the end of file would create an improper archive,
588 * archive if we can avoid it. Of course trying to archive files that are
592 * 0 ok, -1 if archive write failure. a short read of the file returns a
593 * 0, but "left" is set to be greater than zero.
601 off_t size = arcn->sb.st_size; in wr_rdfile()
605 * while there are more bytes to write in wr_rdfile()
608 cnt = bufend - bufpt; in wr_rdfile()
611 return(-1); in wr_rdfile()
614 if ((res = read(ifd, bufpt, cnt)) <= 0) in wr_rdfile()
616 size -= res; in wr_rdfile()
622 * or the file read failed. in wr_rdfile()
625 syswarn(1, errno, "Read fault on %s", arcn->org_name); in wr_rdfile()
627 paxwarn(1, "File changed size during read %s", arcn->org_name); in wr_rdfile()
629 syswarn(1, errno, "Failed stat on %s", arcn->org_name); in wr_rdfile()
630 else if (arcn->sb.st_mtime != sb.st_mtime) in wr_rdfile()
631 paxwarn(1, "File %s was modified during copy to archive", in wr_rdfile()
632 arcn->org_name); in wr_rdfile()
639 * extract the contents of a file from the archive. If we are unable to
640 * extract the entire file (due to failure to write the file) we return
642 * many bytes to skip past to find the next archive header. If the failure
643 * was due to an archive read, we will catch that when we try to skip. If
645 * so that it can be compared to the value stored in the header
647 * We call a special function to write the file. This function attempts to
653 * 0 ok, -1 if archive read failure. if we cannot write the entire file,
654 * we return a 0 but "left" is set to be the amount unwritten
661 off_t size = arcn->sb.st_size; in rd_wrfile()
663 char *fnm = arcn->name; in rd_wrfile()
671 * pass the blocksize of the file being written to the write routine, in rd_wrfile()
678 syswarn(0,errno,"Unable to obtain block size for file %s",fnm); in rd_wrfile()
683 * Copy the archive to the file the number of bytes specified. We have in rd_wrfile()
684 * to assume that we want to recover file holes as none of the archive in rd_wrfile()
688 cnt = bufend - bufpt; in rd_wrfile()
690 * if we get a read error, we do not want to skip, as we may in rd_wrfile()
691 * miss a header, so we do not set left, but if we get a write in rd_wrfile()
692 * error, we do want to skip over the unprocessed data. in rd_wrfile()
707 while (--cnt >= 0) in rd_wrfile()
711 size -= res; in rd_wrfile()
716 * gets updated in the file. We force the last block of zeros to be in rd_wrfile()
720 if (isem && (arcn->sb.st_size > 0L)) in rd_wrfile()
724 * if we failed from archive read, we do not want to skip in rd_wrfile()
727 return(-1); in rd_wrfile()
731 * calculated crc to the crc stored in the archive in rd_wrfile()
733 if (docrc && (size == 0L) && (arcn->crc != crc)) in rd_wrfile()
734 paxwarn(1,"Actual crc does not match expected crc %s",arcn->name); in rd_wrfile()
740 * copy the contents of one file to another. used during -rw phase of pax
741 * just as in rd_wrfile() we use a special write function to write the
751 char *fnm = arcn->name; in cp_file()
760 * write instead of file write. in cp_file()
762 if (((off_t)(arcn->sb.st_blocks * BLKMULT)) >= arcn->sb.st_size) in cp_file()
766 * pass the blocksize of the file being written to the write routine, in cp_file()
773 syswarn(0,errno,"Unable to obtain block size for file %s",fnm); in cp_file()
777 * read the source file and copy to destination file until EOF in cp_file()
780 if ((cnt = read(fd1, buf, blksz)) <= 0) in cp_file()
783 res = write(fd2, buf, cnt); in cp_file()
792 * check to make sure the copy is valid. in cp_file()
795 syswarn(1, errno, "Failed write during copy of %s to %s", in cp_file()
796 arcn->org_name, arcn->name); in cp_file()
797 else if (cpcnt != arcn->sb.st_size) in cp_file()
798 paxwarn(1, "File %s changed size during copy to %s", in cp_file()
799 arcn->org_name, arcn->name); in cp_file()
801 syswarn(1, errno, "Failed stat of %s", arcn->org_name); in cp_file()
802 else if (arcn->sb.st_mtime != sb.st_mtime) in cp_file()
803 paxwarn(1, "File %s was modified during copy to %s", in cp_file()
804 arcn->org_name, arcn->name); in cp_file()
808 * gets updated in the file. We force the last block of zeros to be in cp_file()
812 if (!no_hole && isem && (arcn->sb.st_size > 0L)) in cp_file()
819 * fill the read buffer with the next record (or what we can get) from
822 * Number of bytes of data in the read buffer, -1 for read error, and
837 * try to fill the buffer. on error the next archive volume is in buf_fill()
848 * errors require resync, EOF goes to next archive in buf_fill()
862 return(-1); in buf_fill()
867 * force the write buffer to the archive. We are passed the number of
871 * 0 if all is ok, -1 when a write error occurs.
883 * volume, prompt for the next volume. (The non-standard -R flag). in buf_flush()
884 * NOTE: If the wrlimit is smaller than wrcnt, we will always write in buf_flush()
885 * at least one record. We always round limit UP to next blocksize. in buf_flush()
892 return(-1); in buf_flush()
898 * write blocksize. if so we figure out if we need to write in buf_flush()
909 push = bufcnt - blksz; in buf_flush()
913 * We have enough data to write at least one archive block in buf_flush()
917 * write a block and check if it all went out ok in buf_flush()
922 * the write went ok in buf_flush()
927 /* we have extra data to push to the front. in buf_flush()
929 * so we loop back to write again in buf_flush()
934 push -= blksz; in buf_flush()
942 * Oh drat we got a partial write! in buf_flush()
950 cnt = bufcnt - cnt; in buf_flush()
953 if (!frmt->blkalgn || ((cnt % frmt->blkalgn) == 0)) in buf_flush()
959 * All done, go to next archive in buf_flush()
974 push = bufcnt - blksz; in buf_flush()
978 * write failed, stop pax. we must not create a bad archive! in buf_flush()
981 return(-1); in buf_flush()