/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 1992 Keith Muller.4* Copyright (c) 1992, 19935* The Regents of the University of California. All rights reserved.6*7* This code is derived from software contributed to Berkeley by8* Keith Muller of the University of California, San Diego.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions and the following disclaimer.15* 2. Redistributions in binary form must reproduce the above copyright16* notice, this list of conditions and the following disclaimer in the17* documentation and/or other materials provided with the distribution.18* 3. Neither the name of the University nor the names of its contributors19* may be used to endorse or promote products derived from this software20* without specific prior written permission.21*22* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND23* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE24* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE25* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE26* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL27* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS28* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)29* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT30* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY31* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF32* SUCH DAMAGE.33*/3435#include <sys/types.h>36#include <sys/ioctl.h>37#include <sys/mtio.h>38#include <sys/stat.h>39#include <sys/wait.h>40#include <err.h>41#include <errno.h>42#include <fcntl.h>43#include <signal.h>44#include <stdint.h>45#include <stdio.h>46#include <string.h>47#include <stdlib.h>48#include <unistd.h>49#include "pax.h"50#include "options.h"51#include "extern.h"5253/*54* Routines which deal directly with the archive I/O device/file.55*/5657#define DMOD 0666 /* default mode of created archives */58#define EXT_MODE O_RDONLY /* open mode for list/extract */59#define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */60#define APP_MODE O_RDWR /* mode for append */6162static char none[] = "<NONE>"; /* pseudo name for no file */63static char stdo[] = "<STDOUT>"; /* pseudo name for stdout */64static char stdn[] = "<STDIN>"; /* pseudo name for stdin */65static int arfd = -1; /* archive file descriptor */66static int artyp = ISREG; /* archive type: file/FIFO/tape */67static int arvol = 1; /* archive volume number */68static int lstrval = -1; /* return value from last i/o */69static int io_ok; /* i/o worked on volume after resync */70static int did_io; /* did i/o ever occur on volume? */71static int done; /* set via tty termination */72static struct stat arsb; /* stat of archive device at open */73static int invld_rec; /* tape has out of spec record size */74static int wr_trail = 1; /* trailer was rewritten in append */75static int can_unlnk = 0; /* do we unlink null archives? */76const char *arcname; /* printable name of archive */77const char *gzip_program; /* name of gzip program */78static pid_t zpid = -1; /* pid of child process */7980static int get_phys(void);81static void ar_start_gzip(int, const char *, int);8283/*84* ar_open()85* Opens the next archive volume. Determines the type of the device and86* sets up block sizes as required by the archive device and the format.87* Note: we may be called with name == NULL on the first open only.88* Return:89* -1 on failure, 0 otherwise90*/9192int93ar_open(const char *name)94{95struct mtget mb;9697if (arfd != -1)98(void)close(arfd);99arfd = -1;100can_unlnk = did_io = io_ok = invld_rec = 0;101artyp = ISREG;102flcnt = 0;103104/*105* open based on overall operation mode106*/107switch (act) {108case LIST:109case EXTRACT:110if (name == NULL) {111arfd = STDIN_FILENO;112arcname = stdn;113} else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)114syswarn(0, errno, "Failed open to read on %s", name);115if (arfd != -1 && gzip_program != NULL)116ar_start_gzip(arfd, gzip_program, 0);117break;118case ARCHIVE:119if (name == NULL) {120arfd = STDOUT_FILENO;121arcname = stdo;122} else if ((arfd = open(name, AR_MODE, DMOD)) < 0)123syswarn(0, errno, "Failed open to write on %s", name);124else125can_unlnk = 1;126if (arfd != -1 && gzip_program != NULL)127ar_start_gzip(arfd, gzip_program, 1);128break;129case APPND:130if (name == NULL) {131arfd = STDOUT_FILENO;132arcname = stdo;133} else if ((arfd = open(name, APP_MODE, DMOD)) < 0)134syswarn(0, errno, "Failed open to read/write on %s",135name);136break;137case COPY:138/*139* arfd not used in COPY mode140*/141arcname = none;142lstrval = 1;143return(0);144}145if (arfd < 0)146return(-1);147148if (chdname != NULL)149if (chdir(chdname) != 0) {150syswarn(1, errno, "Failed chdir to %s", chdname);151return(-1);152}153/*154* set up is based on device type155*/156if (fstat(arfd, &arsb) < 0) {157syswarn(0, errno, "Failed stat on %s", arcname);158(void)close(arfd);159arfd = -1;160can_unlnk = 0;161return(-1);162}163if (S_ISDIR(arsb.st_mode)) {164paxwarn(0, "Cannot write an archive on top of a directory %s",165arcname);166(void)close(arfd);167arfd = -1;168can_unlnk = 0;169return(-1);170}171172if (S_ISCHR(arsb.st_mode))173artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;174else if (S_ISBLK(arsb.st_mode))175artyp = ISBLK;176else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))177artyp = ISPIPE;178else179artyp = ISREG;180181/*182* make sure we beyond any doubt that we only can unlink regular files183* we created184*/185if (artyp != ISREG)186can_unlnk = 0;187/*188* if we are writing, we are done189*/190if (act == ARCHIVE) {191blksz = rdblksz = wrblksz;192lstrval = 1;193return(0);194}195196/*197* set default blksz on read. APPNDs writes rdblksz on the last volume198* On all new archive volumes, we shift to wrblksz (if the user199* specified one, otherwise we will continue to use rdblksz). We200* must set blocksize based on what kind of device the archive is201* stored.202*/203switch(artyp) {204case ISTAPE:205/*206* Tape drives come in at least two flavors. Those that support207* variable sized records and those that have fixed sized208* records. They must be treated differently. For tape drives209* that support variable sized records, we must make large210* reads to make sure we get the entire record, otherwise we211* will just get the first part of the record (up to size we212* asked). Tapes with fixed sized records may or may not return213* multiple records in a single read. We really do not care214* what the physical record size is UNLESS we are going to215* append. (We will need the physical block size to rewrite216* the trailer). Only when we are appending do we go to the217* effort to figure out the true PHYSICAL record size.218*/219blksz = rdblksz = MAXBLK;220break;221case ISPIPE:222case ISBLK:223case ISCHR:224/*225* Blocksize is not a major issue with these devices (but must226* be kept a multiple of 512). If the user specified a write227* block size, we use that to read. Under append, we must228* always keep blksz == rdblksz. Otherwise we go ahead and use229* the device optimal blocksize as (and if) returned by stat230* and if it is within pax specs.231*/232if ((act == APPND) && wrblksz) {233blksz = rdblksz = wrblksz;234break;235}236237if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&238((arsb.st_blksize % BLKMULT) == 0))239rdblksz = arsb.st_blksize;240else241rdblksz = DEVBLK;242/*243* For performance go for large reads when we can without harm244*/245if ((act == APPND) || (artyp == ISCHR))246blksz = rdblksz;247else248blksz = MAXBLK;249break;250case ISREG:251/*252* if the user specified wrblksz works, use it. Under appends253* we must always keep blksz == rdblksz254*/255if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){256blksz = rdblksz = wrblksz;257break;258}259/*260* See if we can find the blocking factor from the file size261*/262for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)263if ((arsb.st_size % rdblksz) == 0)264break;265/*266* When we cannot find a match, we may have a flawed archive.267*/268if (rdblksz <= 0)269rdblksz = FILEBLK;270/*271* for performance go for large reads when we can272*/273if (act == APPND)274blksz = rdblksz;275else276blksz = MAXBLK;277break;278default:279/*280* should never happen, worst case, slow...281*/282blksz = rdblksz = BLKMULT;283break;284}285lstrval = 1;286return(0);287}288289/*290* ar_close()291* closes archive device, increments volume number, and prints i/o summary292*/293void294ar_close(void)295{296int status;297298if (arfd < 0) {299did_io = io_ok = flcnt = 0;300return;301}302303/*304* Close archive file. This may take a LONG while on tapes (we may be305* forced to wait for the rewind to complete) so tell the user what is306* going on (this avoids the user hitting control-c thinking pax is307* broken).308*/309if (vflag && (artyp == ISTAPE)) {310if (vfpart)311(void)putc('\n', listf);312(void)fprintf(listf,313"%s: Waiting for tape drive close to complete...",314argv0);315(void)fflush(listf);316}317318/*319* if nothing was written to the archive (and we created it), we remove320* it321*/322if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&323(arsb.st_size == 0)) {324(void)unlink(arcname);325can_unlnk = 0;326}327328/*329* for a quick extract/list, pax frequently exits before the child330* process is done331*/332if ((act == LIST || act == EXTRACT) && nflag && zpid > 0)333kill(zpid, SIGINT);334335(void)close(arfd);336337/* Do not exit before child to ensure data integrity */338if (zpid > 0)339waitpid(zpid, &status, 0);340341if (vflag && (artyp == ISTAPE)) {342(void)fputs("done.\n", listf);343vfpart = 0;344(void)fflush(listf);345}346arfd = -1;347348if (!io_ok && !did_io) {349flcnt = 0;350return;351}352did_io = io_ok = 0;353354/*355* The volume number is only increased when the last device has data356* and we have already determined the archive format.357*/358if (frmt != NULL)359++arvol;360361if (!vflag) {362flcnt = 0;363return;364}365366/*367* Print out a summary of I/O for this archive volume.368*/369if (vfpart) {370(void)putc('\n', listf);371vfpart = 0;372}373374/*375* If we have not determined the format yet, we just say how many bytes376* we have skipped over looking for a header to id. There is no way we377* could have written anything yet.378*/379if (frmt == NULL) {380(void)fprintf(listf, "%s: unknown format, %ju bytes skipped.\n",381argv0, (uintmax_t)rdcnt);382(void)fflush(listf);383flcnt = 0;384return;385}386387if (strcmp(NM_CPIO, argv0) == 0)388(void)fprintf(listf, "%llu blocks\n",389(unsigned long long)((rdcnt ? rdcnt : wrcnt) / 5120));390else if (strcmp(NM_TAR, argv0) != 0)391(void)fprintf(listf,392"%s: %s vol %d, %ju files, %ju bytes read, %ju bytes written.\n",393argv0, frmt->name, arvol-1, (uintmax_t)flcnt,394(uintmax_t)rdcnt, (uintmax_t)wrcnt);395(void)fflush(listf);396flcnt = 0;397}398399/*400* ar_drain()401* drain any archive format independent padding from an archive read402* from a socket or a pipe. This is to prevent the process on the403* other side of the pipe from getting a SIGPIPE (pax will stop404* reading an archive once a format dependent trailer is detected).405*/406void407ar_drain(void)408{409int res;410char drbuf[MAXBLK];411412/*413* we only drain from a pipe/socket. Other devices can be closed414* without reading up to end of file. We sure hope that pipe is closed415* on the other side so we will get an EOF.416*/417if ((artyp != ISPIPE) || (lstrval <= 0))418return;419420/*421* keep reading until pipe is drained422*/423while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)424;425lstrval = res;426}427428/*429* ar_set_wr()430* Set up device right before switching from read to write in an append.431* device dependent code (if required) to do this should be added here.432* For all archive devices we are already positioned at the place we want433* to start writing when this routine is called.434* Return:435* 0 if all ready to write, -1 otherwise436*/437438int439ar_set_wr(void)440{441off_t cpos;442443/*444* we must make sure the trailer is rewritten on append, ar_next()445* will stop us if the archive containing the trailer was not written446*/447wr_trail = 0;448449/*450* Add any device dependent code as required here451*/452if (artyp != ISREG)453return(0);454/*455* Ok we have an archive in a regular file. If we were rewriting a456* file, we must get rid of all the stuff after the current offset457* (it was not written by pax).458*/459if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||460(ftruncate(arfd, cpos) < 0)) {461syswarn(1, errno, "Unable to truncate archive file");462return(-1);463}464return(0);465}466467/*468* ar_app_ok()469* check if the last volume in the archive allows appends. We cannot check470* this until we are ready to write since there is no spec that says all471* volumes in a single archive have to be of the same type...472* Return:473* 0 if we can append, -1 otherwise.474*/475476int477ar_app_ok(void)478{479if (artyp == ISPIPE) {480paxwarn(1, "Cannot append to an archive obtained from a pipe.");481return(-1);482}483484if (!invld_rec)485return(0);486paxwarn(1,"Cannot append, device record size %d does not support %s spec",487rdblksz, argv0);488return(-1);489}490491/*492* ar_read()493* read up to a specified number of bytes from the archive into the494* supplied buffer. When dealing with tapes we may not always be able to495* read what we want.496* Return:497* Number of bytes in buffer. 0 for end of file, -1 for a read error.498*/499500int501ar_read(char *buf, int cnt)502{503int res = 0;504505/*506* if last i/o was in error, no more reads until reset or new volume507*/508if (lstrval <= 0)509return(lstrval);510511/*512* how we read must be based on device type513*/514switch (artyp) {515case ISTAPE:516if ((res = read(arfd, buf, cnt)) > 0) {517/*518* CAUTION: tape systems may not always return the same519* sized records so we leave blksz == MAXBLK. The520* physical record size that a tape drive supports is521* very hard to determine in a uniform and portable522* manner.523*/524io_ok = 1;525if (res != rdblksz) {526/*527* Record size changed. If this happens on528* any record after the first, we probably have529* a tape drive which has a fixed record size530* (we are getting multiple records in a single531* read). Watch out for record blocking that532* violates pax spec (must be a multiple of533* BLKMULT).534*/535rdblksz = res;536if (rdblksz % BLKMULT)537invld_rec = 1;538}539return(res);540}541break;542case ISREG:543case ISBLK:544case ISCHR:545case ISPIPE:546default:547/*548* Files are so easy to deal with. These other things cannot549* be trusted at all. So when we are dealing with character550* devices and pipes we just take what they have ready for us551* and return. Trying to do anything else with them runs the552* risk of failure.553*/554if ((res = read(arfd, buf, cnt)) > 0) {555io_ok = 1;556return(res);557}558break;559}560561/*562* We are in trouble at this point, something is broken...563*/564lstrval = res;565if (res < 0)566syswarn(1, errno, "Failed read on archive volume %d", arvol);567else568paxwarn(0, "End of archive volume %d reached", arvol);569return(res);570}571572/*573* ar_write()574* Write a specified number of bytes in supplied buffer to the archive575* device so it appears as a single "block". Deals with errors and tries576* to recover when faced with short writes.577* Return:578* Number of bytes written. 0 indicates end of volume reached and with no579* flaws (as best that can be detected). A -1 indicates an unrecoverable580* error in the archive occurred.581*/582583int584ar_write(char *buf, int bsz)585{586int res;587off_t cpos;588589/*590* do not allow pax to create a "bad" archive. Once a write fails on591* an archive volume prevent further writes to it.592*/593if (lstrval <= 0)594return(lstrval);595596if ((res = write(arfd, buf, bsz)) == bsz) {597wr_trail = 1;598io_ok = 1;599return(bsz);600}601/*602* write broke, see what we can do with it. We try to send any partial603* writes that may violate pax spec to the next archive volume.604*/605if (res < 0)606lstrval = res;607else608lstrval = 0;609610switch (artyp) {611case ISREG:612if ((res > 0) && (res % BLKMULT)) {613/*614* try to fix up partial writes which are not BLKMULT615* in size by forcing the runt record to next archive616* volume617*/618if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)619break;620cpos -= (off_t)res;621if (ftruncate(arfd, cpos) < 0)622break;623res = lstrval = 0;624break;625}626if (res >= 0)627break;628/*629* if file is out of space, handle it like a return of 0630*/631if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT))632res = lstrval = 0;633break;634case ISTAPE:635case ISCHR:636case ISBLK:637if (res >= 0)638break;639if (errno == EACCES) {640paxwarn(0, "Write failed, archive is write protected.");641res = lstrval = 0;642return(0);643}644/*645* see if we reached the end of media, if so force a change to646* the next volume647*/648if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))649res = lstrval = 0;650break;651case ISPIPE:652default:653/*654* we cannot fix errors to these devices655*/656break;657}658659/*660* Better tell the user the bad news...661* if this is a block aligned archive format, we may have a bad archive662* if the format wants the header to start at a BLKMULT boundary. While663* we can deal with the mis-aligned data, it violates spec and other664* archive readers will likely fail. If the format is not block665* aligned, the user may be lucky (and the archive is ok).666*/667if (res >= 0) {668if (res > 0)669wr_trail = 1;670io_ok = 1;671}672673/*674* If we were trying to rewrite the trailer and it didn't work, we675* must quit right away.676*/677if (!wr_trail && (res <= 0)) {678paxwarn(1,"Unable to append, trailer re-write failed. Quitting.");679return(res);680}681682if (res == 0)683paxwarn(0, "End of archive volume %d reached", arvol);684else if (res < 0)685syswarn(1, errno, "Failed write to archive volume: %d", arvol);686else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))687paxwarn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");688else689paxwarn(1,"WARNING: partial archive write. Archive IS FLAWED");690return(res);691}692693/*694* ar_rdsync()695* Try to move past a bad spot on a flawed archive as needed to continue696* I/O. Clears error flags to allow I/O to continue.697* Return:698* 0 when ok to try i/o again, -1 otherwise.699*/700701int702ar_rdsync(void)703{704long fsbz;705off_t cpos;706off_t mpos;707struct mtop mb;708709/*710* Fail resync attempts at user request (done) or if this is going to be711* an update/append to an existing archive. If last i/o hit media end,712* we need to go to the next volume not try a resync.713*/714if ((done > 0) || (lstrval == 0))715return(-1);716717if ((act == APPND) || (act == ARCHIVE)) {718paxwarn(1, "Cannot allow updates to an archive with flaws.");719return(-1);720}721if (io_ok)722did_io = 1;723724switch(artyp) {725case ISTAPE:726/*727* if the last i/o was a successful data transfer, we assume728* the fault is just a bad record on the tape that we are now729* past. If we did not get any data since the last resync try730* to move the tape forward one PHYSICAL record past any731* damaged tape section. Some tape drives are stubborn and need732* to be pushed.733*/734if (io_ok) {735io_ok = 0;736lstrval = 1;737break;738}739mb.mt_op = MTFSR;740mb.mt_count = 1;741if (ioctl(arfd, MTIOCTOP, &mb) < 0)742break;743lstrval = 1;744break;745case ISREG:746case ISCHR:747case ISBLK:748/*749* try to step over the bad part of the device.750*/751io_ok = 0;752if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))753fsbz = BLKMULT;754if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)755break;756mpos = fsbz - (cpos % (off_t)fsbz);757if (lseek(arfd, mpos, SEEK_CUR) < 0)758break;759lstrval = 1;760break;761case ISPIPE:762default:763/*764* cannot recover on these archive device types765*/766io_ok = 0;767break;768}769if (lstrval <= 0) {770paxwarn(1, "Unable to recover from an archive read failure.");771return(-1);772}773paxwarn(0, "Attempting to recover from an archive read failure.");774return(0);775}776777/*778* ar_fow()779* Move the I/O position within the archive forward the specified number of780* bytes as supported by the device. If we cannot move the requested781* number of bytes, return the actual number of bytes moved in skipped.782* Return:783* 0 if moved the requested distance, -1 on complete failure, 1 on784* partial move (the amount moved is in skipped)785*/786787int788ar_fow(off_t sksz, off_t *skipped)789{790off_t cpos;791off_t mpos;792793*skipped = 0;794if (sksz <= 0)795return(0);796797/*798* we cannot move forward at EOF or error799*/800if (lstrval <= 0)801return(lstrval);802803/*804* Safer to read forward on devices where it is hard to find the end of805* the media without reading to it. With tapes we cannot be sure of the806* number of physical blocks to skip (we do not know physical block807* size at this point), so we must only read forward on tapes!808*/809if (artyp != ISREG)810return(0);811812/*813* figure out where we are in the archive814*/815if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {816/*817* we can be asked to move farther than there are bytes in this818* volume, if so, just go to file end and let normal buf_fill()819* deal with the end of file (it will go to next volume by820* itself)821*/822if ((mpos = cpos + sksz) > arsb.st_size) {823*skipped = arsb.st_size - cpos;824mpos = arsb.st_size;825} else826*skipped = sksz;827if (lseek(arfd, mpos, SEEK_SET) >= 0)828return(0);829}830syswarn(1, errno, "Forward positioning operation on archive failed");831lstrval = -1;832return(-1);833}834835/*836* ar_rev()837* move the i/o position within the archive backwards the specified byte838* count as supported by the device. With tapes drives we RESET rdblksz to839* the PHYSICAL blocksize.840* NOTE: We should only be called to move backwards so we can rewrite the841* last records (the trailer) of an archive (APPEND).842* Return:843* 0 if moved the requested distance, -1 on complete failure844*/845846int847ar_rev(off_t sksz)848{849off_t cpos;850struct mtop mb;851int phyblk;852853/*854* make sure we do not have try to reverse on a flawed archive855*/856if (lstrval < 0)857return(lstrval);858859switch(artyp) {860case ISPIPE:861if (sksz <= 0)862break;863/*864* cannot go backwards on these critters865*/866paxwarn(1, "Reverse positioning on pipes is not supported.");867lstrval = -1;868return(-1);869case ISREG:870case ISBLK:871case ISCHR:872default:873if (sksz <= 0)874break;875876/*877* For things other than files, backwards movement has a very878* high probability of failure as we really do not know the879* true attributes of the device we are talking to (the device880* may not even have the ability to lseek() in any direction).881* First we figure out where we are in the archive.882*/883if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {884syswarn(1, errno,885"Unable to obtain current archive byte offset");886lstrval = -1;887return(-1);888}889890/*891* we may try to go backwards past the start when the archive892* is only a single record. If this happens and we are on a893* multi volume archive, we need to go to the end of the894* previous volume and continue our movement backwards from895* there.896*/897if ((cpos -= sksz) < (off_t)0L) {898if (arvol > 1) {899/*900* this should never happen901*/902paxwarn(1,"Reverse position on previous volume.");903lstrval = -1;904return(-1);905}906cpos = (off_t)0L;907}908if (lseek(arfd, cpos, SEEK_SET) < 0) {909syswarn(1, errno, "Unable to seek archive backwards");910lstrval = -1;911return(-1);912}913break;914case ISTAPE:915/*916* Calculate and move the proper number of PHYSICAL tape917* blocks. If the sksz is not an even multiple of the physical918* tape size, we cannot do the move (this should never happen).919* (We also cannot handle trailers spread over two vols).920* get_phys() also makes sure we are in front of the filemark.921*/922if ((phyblk = get_phys()) <= 0) {923lstrval = -1;924return(-1);925}926927/*928* make sure future tape reads only go by physical tape block929* size (set rdblksz to the real size).930*/931rdblksz = phyblk;932933/*934* if no movement is required, just return (we must be after935* get_phys() so the physical blocksize is properly set)936*/937if (sksz <= 0)938break;939940/*941* ok we have to move. Make sure the tape drive can do it.942*/943if (sksz % phyblk) {944paxwarn(1,945"Tape drive unable to backspace requested amount");946lstrval = -1;947return(-1);948}949950/*951* move backwards the requested number of bytes952*/953mb.mt_op = MTBSR;954mb.mt_count = sksz/phyblk;955if (ioctl(arfd, MTIOCTOP, &mb) < 0) {956syswarn(1,errno, "Unable to backspace tape %d blocks.",957mb.mt_count);958lstrval = -1;959return(-1);960}961break;962}963lstrval = 1;964return(0);965}966967/*968* get_phys()969* Determine the physical block size on a tape drive. We need the physical970* block size so we know how many bytes we skip over when we move with971* mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when972* return.973* This is one really SLOW routine...974* Return:975* physical block size if ok (ok > 0), -1 otherwise976*/977978static int979get_phys(void)980{981int padsz = 0;982int res;983int phyblk;984struct mtop mb;985char scbuf[MAXBLK];986987/*988* move to the file mark, and then back up one record and read it.989* this should tell us the physical record size the tape is using.990*/991if (lstrval == 1) {992/*993* we know we are at file mark when we get back a 0 from994* read()995*/996while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)997padsz += res;998if (res < 0) {999syswarn(1, errno, "Unable to locate tape filemark.");1000return(-1);1001}1002}10031004/*1005* move backwards over the file mark so we are at the end of the1006* last record.1007*/1008mb.mt_op = MTBSF;1009mb.mt_count = 1;1010if (ioctl(arfd, MTIOCTOP, &mb) < 0) {1011syswarn(1, errno, "Unable to backspace over tape filemark.");1012return(-1);1013}10141015/*1016* move backwards so we are in front of the last record and read it to1017* get physical tape blocksize.1018*/1019mb.mt_op = MTBSR;1020mb.mt_count = 1;1021if (ioctl(arfd, MTIOCTOP, &mb) < 0) {1022syswarn(1, errno, "Unable to backspace over last tape block.");1023return(-1);1024}1025if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {1026syswarn(1, errno, "Cannot determine archive tape blocksize.");1027return(-1);1028}10291030/*1031* read forward to the file mark, then back up in front of the filemark1032* (this is a bit paranoid, but should be safe to do).1033*/1034while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)1035;1036if (res < 0) {1037syswarn(1, errno, "Unable to locate tape filemark.");1038return(-1);1039}1040mb.mt_op = MTBSF;1041mb.mt_count = 1;1042if (ioctl(arfd, MTIOCTOP, &mb) < 0) {1043syswarn(1, errno, "Unable to backspace over tape filemark.");1044return(-1);1045}10461047/*1048* set lstrval so we know that the filemark has not been seen1049*/1050lstrval = 1;10511052/*1053* return if there was no padding1054*/1055if (padsz == 0)1056return(phyblk);10571058/*1059* make sure we can move backwards over the padding. (this should1060* never fail).1061*/1062if (padsz % phyblk) {1063paxwarn(1, "Tape drive unable to backspace requested amount");1064return(-1);1065}10661067/*1068* move backwards over the padding so the head is where it was when1069* we were first called (if required).1070*/1071mb.mt_op = MTBSR;1072mb.mt_count = padsz/phyblk;1073if (ioctl(arfd, MTIOCTOP, &mb) < 0) {1074syswarn(1,errno,"Unable to backspace tape over %d pad blocks",1075mb.mt_count);1076return(-1);1077}1078return(phyblk);1079}10801081/*1082* ar_next()1083* prompts the user for the next volume in this archive. For some devices1084* we may allow the media to be changed. Otherwise a new archive is1085* prompted for. By pax spec, if there is no controlling tty or an eof is1086* read on tty input, we must quit pax.1087* Return:1088* 0 when ready to continue, -1 when all done1089*/10901091int1092ar_next(void)1093{1094static char *arcbuf;1095char buf[PAXPATHLEN+2];1096sigset_t o_mask;10971098/*1099* WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so1100* things like writing EOF etc will be done) (Watch out ar_close() can1101* also be called via a signal handler, so we must prevent a race.1102*/1103if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)1104syswarn(0, errno, "Unable to set signal mask");1105ar_close();1106if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0)1107syswarn(0, errno, "Unable to restore signal mask");11081109if (done || !wr_trail || Oflag || strcmp(NM_TAR, argv0) == 0)1110return(-1);11111112tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);11131114/*1115* if i/o is on stdin or stdout, we cannot reopen it (we do not know1116* the name), the user will be forced to type it in.1117*/1118if (strcmp(arcname, stdo) && strcmp(arcname, stdn) && (artyp != ISREG)1119&& (artyp != ISPIPE)) {1120if (artyp == ISTAPE) {1121tty_prnt("%s ready for archive tape volume: %d\n",1122arcname, arvol);1123tty_prnt("Load the NEXT TAPE on the tape drive");1124} else {1125tty_prnt("%s ready for archive volume: %d\n",1126arcname, arvol);1127tty_prnt("Load the NEXT STORAGE MEDIA (if required)");1128}11291130if ((act == ARCHIVE) || (act == APPND))1131tty_prnt(" and make sure it is WRITE ENABLED.\n");1132else1133tty_prnt("\n");11341135for(;;) {1136tty_prnt("Type \"y\" to continue, \".\" to quit %s,",1137argv0);1138tty_prnt(" or \"s\" to switch to new device.\nIf you");1139tty_prnt(" cannot change storage media, type \"s\"\n");1140tty_prnt("Is the device ready and online? > ");11411142if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){1143done = 1;1144lstrval = -1;1145tty_prnt("Quitting %s!\n", argv0);1146vfpart = 0;1147return(-1);1148}11491150if ((buf[0] == '\0') || (buf[1] != '\0')) {1151tty_prnt("%s unknown command, try again\n",buf);1152continue;1153}11541155switch (buf[0]) {1156case 'y':1157case 'Y':1158/*1159* we are to continue with the same device1160*/1161if (ar_open(arcname) >= 0)1162return(0);1163tty_prnt("Cannot re-open %s, try again\n",1164arcname);1165continue;1166case 's':1167case 'S':1168/*1169* user wants to open a different device1170*/1171tty_prnt("Switching to a different archive\n");1172break;1173default:1174tty_prnt("%s unknown command, try again\n",buf);1175continue;1176}1177break;1178}1179} else1180tty_prnt("Ready for archive volume: %d\n", arvol);11811182/*1183* have to go to a different archive1184*/1185for (;;) {1186tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);1187tty_prnt("Archive name > ");11881189if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {1190done = 1;1191lstrval = -1;1192tty_prnt("Quitting %s!\n", argv0);1193vfpart = 0;1194return(-1);1195}1196if (buf[0] == '\0') {1197tty_prnt("Empty file name, try again\n");1198continue;1199}1200if (!strcmp(buf, "..")) {1201tty_prnt("Illegal file name: .. try again\n");1202continue;1203}1204if (strlen(buf) > PAXPATHLEN) {1205tty_prnt("File name too long, try again\n");1206continue;1207}12081209/*1210* try to open new archive1211*/1212if (ar_open(buf) >= 0) {1213free(arcbuf);1214if ((arcbuf = strdup(buf)) == NULL) {1215done = 1;1216lstrval = -1;1217paxwarn(0, "Cannot save archive name.");1218return(-1);1219}1220arcname = arcbuf;1221break;1222}1223tty_prnt("Cannot open %s, try again\n", buf);1224continue;1225}1226return(0);1227}12281229/*1230* ar_start_gzip()1231* starts the gzip compression/decompression process as a child, using magic1232* to keep the fd the same in the calling function (parent).1233*/1234void1235ar_start_gzip(int fd, const char *gzip_prog, int wr)1236{1237int fds[2];1238const char *gzip_flags;12391240if (pipe(fds) < 0)1241err(1, "could not pipe");1242zpid = fork();1243if (zpid < 0)1244err(1, "could not fork");12451246/* parent */1247if (zpid) {1248if (wr)1249dup2(fds[1], fd);1250else1251dup2(fds[0], fd);1252close(fds[0]);1253close(fds[1]);1254} else {1255if (wr) {1256dup2(fds[0], STDIN_FILENO);1257dup2(fd, STDOUT_FILENO);1258gzip_flags = "-c";1259} else {1260dup2(fds[1], STDOUT_FILENO);1261dup2(fd, STDIN_FILENO);1262gzip_flags = "-dc";1263}1264close(fds[0]);1265close(fds[1]);1266if (execlp(gzip_prog, gzip_prog, gzip_flags,1267(char *)NULL) < 0)1268err(1, "could not exec");1269/* NOTREACHED */1270}1271}127212731274