157193Smuller /*- 257193Smuller * Copyright (c) 1992 Keith Muller. 357193Smuller * Copyright (c) 1992 The Regents of the University of California. 457193Smuller * All rights reserved. 557193Smuller * 657193Smuller * This code is derived from software contributed to Berkeley by 757193Smuller * Keith Muller of the University of California, San Diego. 857193Smuller * 957193Smuller * %sccs.include.redist.c% 1057193Smuller */ 1157193Smuller 1257193Smuller #ifndef lint 13*57535Smuller static char sccsid[] = "@(#)ar_io.c 1.2 (Berkeley) 01/14/93"; 1457193Smuller #endif /* not lint */ 1557193Smuller 1657193Smuller #include <sys/types.h> 1757193Smuller #include <sys/time.h> 1857193Smuller #include <sys/stat.h> 1957193Smuller #include <sys/ioctl.h> 2057193Smuller #include <sys/mtio.h> 2157193Smuller #include <sys/param.h> 2257193Smuller #include <signal.h> 2357193Smuller #include <string.h> 2457193Smuller #include <fcntl.h> 2557193Smuller #include <unistd.h> 2657193Smuller #include <stdio.h> 2757193Smuller #include <ctype.h> 2857193Smuller #include <errno.h> 2957193Smuller #include <stdlib.h> 3057193Smuller #include "pax.h" 3157193Smuller #include "extern.h" 3257193Smuller 3357193Smuller /* 34*57535Smuller * Routines which deal directly with the archive I/O device/file. 3557193Smuller */ 3657193Smuller 3757193Smuller #define DMOD 0666 /* default mode of created archives */ 3857193Smuller #define EXT_MODE O_RDONLY /* open mode for list/extract */ 3957193Smuller #define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */ 4057193Smuller #define APP_MODE O_RDWR /* mode for append */ 4157193Smuller #define STDO "<STDOUT>" /* psuedo name for stdout */ 4257193Smuller #define STDN "<STDIN>" /* psuedo name for stdin */ 4357193Smuller static int arfd = -1; /* archive file descriptor */ 4457193Smuller static int artyp; /* archive type: file/FIFO/tape */ 4557193Smuller static int arvol = 1; /* archive volume number */ 4657193Smuller static int lstrval = -1; /* return value from last i/o */ 4757193Smuller static int io_ok; /* i/o worked on volume after resync */ 48*57535Smuller static int did_io; /* did i/o ever occur on volume? */ 4957193Smuller static int done; /* set via tty termination */ 5057193Smuller static struct stat arsb; /* stat of archive device at open */ 5157193Smuller static int invld_rec; /* tape has out of spec record size */ 5257193Smuller static int phyblk; /* size of physical block on TAPE */ 5357193Smuller char *arcname; /* printable name of archive */ 5457193Smuller 5557193Smuller static int get_phys __P((void)); 5657193Smuller extern sigset_t s_mask; 5757193Smuller 5857193Smuller /* 5957193Smuller * ar_open() 6057193Smuller * Opens the next archive volume. Determines the type of the device and 6157193Smuller * sets up block sizes as required by the archive device and the format. 6257193Smuller * Note: we may be called with name == NULL on the first open only. 6357193Smuller * Return: 6457193Smuller * -1 on failure, 0 otherwise 6557193Smuller */ 6657193Smuller 6757193Smuller #if __STDC__ 6857193Smuller int 6957193Smuller ar_open(char *name) 7057193Smuller #else 7157193Smuller int 7257193Smuller ar_open(name) 7357193Smuller char *name; 7457193Smuller #endif 7557193Smuller { 7657193Smuller struct mtget mb; 7757193Smuller 7857193Smuller if (arfd != -1) 7957193Smuller (void)close(arfd); 8057193Smuller arfd = -1; 8157193Smuller phyblk = did_io = io_ok = invld_rec = 0; 8257193Smuller flcnt = 0; 8357193Smuller 8457193Smuller /* 8557193Smuller * open based on overall operation mode 8657193Smuller */ 8757193Smuller switch (act) { 8857193Smuller case LIST: 8957193Smuller case EXTRACT: 9057193Smuller if (name == NULL) { 9157193Smuller arfd = STDIN_FILENO; 9257193Smuller arcname = STDN; 9357193Smuller } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0) 94*57535Smuller syswarn(0, errno, "Failed open to read on %s", name); 9557193Smuller break; 9657193Smuller case ARCHIVE: 9757193Smuller if (name == NULL) { 9857193Smuller arfd = STDOUT_FILENO; 9957193Smuller arcname = STDO; 10057193Smuller } else if ((arfd = open(name, AR_MODE, DMOD)) < 0) 101*57535Smuller syswarn(0, errno, "Failed open to write on %s", name); 10257193Smuller break; 10357193Smuller case APPND: 10457193Smuller if (name == NULL) { 10557193Smuller arfd = STDOUT_FILENO; 10657193Smuller arcname = STDO; 10757193Smuller } else if ((arfd = open(name, APP_MODE, DMOD)) < 0) 108*57535Smuller syswarn(0, errno, "Failed open to read/write on %s", 10957193Smuller name); 11057193Smuller break; 11157193Smuller case COPY: 11257193Smuller /* 11357193Smuller * arfd not used in COPY mode 11457193Smuller */ 11557193Smuller arcname = "<NONE>"; 11657193Smuller lstrval = 1; 11757193Smuller return(0); 11857193Smuller } 11957193Smuller if (arfd < 0) 12057193Smuller return(-1); 12157193Smuller 12257193Smuller /* 12357193Smuller * set up is based on device type 12457193Smuller */ 12557193Smuller if (fstat(arfd, &arsb) < 0) { 126*57535Smuller syswarn(0, errno, "Failed stat on %s", arcname); 12757193Smuller return(-1); 12857193Smuller } 12957193Smuller if (S_ISDIR(arsb.st_mode)) { 130*57535Smuller warn(0, "Cannot write an archive on top of a directory %s", 13157193Smuller arcname); 13257193Smuller return(-1); 13357193Smuller } 13457193Smuller if (S_ISCHR(arsb.st_mode)) 13557193Smuller artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE; 13657193Smuller else if (S_ISBLK(arsb.st_mode)) 13757193Smuller artyp = ISBLK; 13857193Smuller else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE)) 13957193Smuller artyp = ISPIPE; 14057193Smuller else 14157193Smuller artyp = ISREG; 14257193Smuller 14357193Smuller /* 144*57535Smuller * if we are writing, we are done 14557193Smuller */ 14657193Smuller if (act == ARCHIVE) { 14757193Smuller blksz = rdblksz = wrblksz; 14857193Smuller lstrval = 1; 14957193Smuller return(0); 15057193Smuller } 15157193Smuller 15257193Smuller /* 15357193Smuller * set default blksz on read. APPNDs writes rdblksz on the last volume 15457193Smuller * On all new archive volumes, we shift to wrblksz (if the user 15557193Smuller * specified one, otherwize we will continue to use rdblksz). We 15657193Smuller * must to set blocksize based on what kind of device the archive is 15757193Smuller * stored. 15857193Smuller */ 15957193Smuller switch(artyp) { 16057193Smuller case ISTAPE: 16157193Smuller /* 16257193Smuller * Tape drives come in at least two flavors. Those that support 16357193Smuller * variable sized records and those that have fixed sized 16457193Smuller * records. They must be treated differently. For tape drives 16557193Smuller * that support variable sized records, we must make large 16657193Smuller * reads to make sure we get the entire record, otherwise we 16757193Smuller * will just get the first part of the record (up to size we 16857193Smuller * asked). Tapes with fixed sized records may or may not return 16957193Smuller * multiple records in a single read. We really do not care 17057193Smuller * what the physical record size is UNLESS we are going to 17157193Smuller * append. (We will need the physical block size to rewrite 17257193Smuller * the trailer). Only when we are appending do we go to the 173*57535Smuller * effort to figure out the true PHYSICAL record size. 17457193Smuller */ 17557193Smuller blksz = rdblksz = MAXBLK; 17657193Smuller break; 17757193Smuller case ISPIPE: 17857193Smuller case ISBLK: 17957193Smuller case ISCHR: 18057193Smuller /* 18157193Smuller * Blocksize is not a major issue with these devices (but must 18257193Smuller * be kept a multiple of 512). If the user specified a write 18357193Smuller * block size, we use that to read. Under append, we must 18457193Smuller * always keep blksz == rdblksz. Otherwise we go ahead and use 18557193Smuller * the device optimal blocksize as (and if) returned by stat 18657193Smuller * and if it is within pax specs. 18757193Smuller */ 18857193Smuller if ((act == APPND) && wrblksz) { 18957193Smuller blksz = rdblksz = wrblksz; 19057193Smuller break; 19157193Smuller } 19257193Smuller 19357193Smuller if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) && 19457193Smuller ((arsb.st_blksize % BLKMULT) == 0)) 19557193Smuller rdblksz = arsb.st_blksize; 19657193Smuller else 19757193Smuller rdblksz = DEVBLK; 19857193Smuller /* 19957193Smuller * For performance go for large reads when we can without harm 20057193Smuller */ 20157193Smuller if ((act == APPND) || (artyp == ISCHR)) 20257193Smuller blksz = rdblksz; 20357193Smuller else 20457193Smuller blksz = MAXBLK; 20557193Smuller break; 20657193Smuller case ISREG: 20757193Smuller /* 20857193Smuller * if the user specified wrblksz works, use it. Under appends 20957193Smuller * we must always keep blksz == rdblksz 21057193Smuller */ 21157193Smuller if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){ 21257193Smuller blksz = rdblksz = wrblksz; 21357193Smuller break; 21457193Smuller } 21557193Smuller /* 21657193Smuller * See if we can find the blocking factor from the file size 21757193Smuller */ 21857193Smuller for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT) 21957193Smuller if ((arsb.st_size % rdblksz) == 0) 22057193Smuller break; 22157193Smuller /* 22257193Smuller * When we cannont find a match, we may have a flawed archive. 22357193Smuller */ 22457193Smuller if (rdblksz <= 0) 22557193Smuller rdblksz = FILEBLK; 22657193Smuller /* 22757193Smuller * for performance go for large reads when we can 22857193Smuller */ 22957193Smuller if (act == APPND) 23057193Smuller blksz = rdblksz; 23157193Smuller else 23257193Smuller blksz = MAXBLK; 23357193Smuller break; 23457193Smuller default: 23557193Smuller /* 23657193Smuller * should never happen, worse case, slow... 23757193Smuller */ 23857193Smuller blksz = rdblksz = BLKMULT; 23957193Smuller break; 24057193Smuller } 24157193Smuller lstrval = 1; 24257193Smuller return(0); 24357193Smuller } 24457193Smuller 24557193Smuller /* 24657193Smuller * ar_close() 24757193Smuller * closes archive device, increments volume number, and prints i/o summary 24857193Smuller */ 24957193Smuller #if __STDC__ 25057193Smuller void 25157193Smuller ar_close(void) 25257193Smuller #else 25357193Smuller void 25457193Smuller ar_close() 25557193Smuller #endif 25657193Smuller { 25757193Smuller FILE *outf; 25857193Smuller 259*57535Smuller if (act == LIST) 260*57535Smuller outf = stdout; 261*57535Smuller else 262*57535Smuller outf = stderr; 263*57535Smuller 264*57535Smuller /* 265*57535Smuller * Close archive file. This may take a LONG while on tapes (we may be 266*57535Smuller * forced to wait for the rewind to complete) so tell the user what is 267*57535Smuller * going on (this avoids the user hitting control-c thinking pax is 268*57535Smuller * broken). 269*57535Smuller */ 270*57535Smuller if (vflag && (arfd >= 0) && (artyp == ISTAPE)) { 271*57535Smuller if (vfpart) { 272*57535Smuller (void)putc('\n', outf); 273*57535Smuller vfpart = 0; 274*57535Smuller } 275*57535Smuller (void)fputs("pax: Waiting for tape drive close to complete...", 276*57535Smuller outf); 277*57535Smuller (void)fflush(outf); 278*57535Smuller } 279*57535Smuller 28057193Smuller (void)close(arfd); 281*57535Smuller 282*57535Smuller if (vflag && (arfd >= 0) && (artyp == ISTAPE)) { 283*57535Smuller (void)fputs("done.\n", outf); 284*57535Smuller (void)fflush(outf); 285*57535Smuller } 28657193Smuller arfd = -1; 287*57535Smuller 28857193Smuller if (!io_ok && !did_io) { 28957193Smuller flcnt = 0; 29057193Smuller return; 29157193Smuller } 29257193Smuller did_io = io_ok = 0; 29357193Smuller 29457193Smuller /* 29557193Smuller * The volume number is only increased when the last device has data 296*57535Smuller * and we have already determined the archive format. 29757193Smuller */ 298*57535Smuller if (frmt != NULL) 299*57535Smuller ++arvol; 300*57535Smuller 30157193Smuller if (!vflag) { 30257193Smuller flcnt = 0; 30357193Smuller return; 30457193Smuller } 30557193Smuller 30657193Smuller /* 30757193Smuller * Print out a summary of I/O for this archive volume. 30857193Smuller */ 30957193Smuller if (vfpart) { 31057193Smuller (void)putc('\n', outf); 31157193Smuller vfpart = 0; 31257193Smuller } 31357193Smuller 314*57535Smuller /* 315*57535Smuller * If we have not determined the format yet, we just say how many bytes 316*57535Smuller * we have skipped over looking for a header to id. there is no way we 317*57535Smuller * could have written anything yet. 318*57535Smuller */ 319*57535Smuller if (frmt == NULL) { 320*57535Smuller # ifdef NET2_STAT 321*57535Smuller (void)fprintf(outf, "pax: unknown format, %lu bytes skipped.\n", 322*57535Smuller # else 323*57535Smuller (void)fprintf(outf, "pax: unknown format, %qu bytes skipped.\n", 324*57535Smuller # endif 325*57535Smuller rdcnt); 326*57535Smuller (void)fflush(outf); 327*57535Smuller flcnt = 0; 328*57535Smuller return; 329*57535Smuller } 330*57535Smuller 33157193Smuller (void)fprintf(outf, 33257193Smuller # ifdef NET2_STAT 333*57535Smuller "pax: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n", 33457193Smuller # else 335*57535Smuller "pax: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n", 33657193Smuller # endif 33757193Smuller frmt->name, arvol-1, flcnt, rdcnt, wrcnt); 33857193Smuller (void)fflush(outf); 33957193Smuller flcnt = 0; 34057193Smuller } 34157193Smuller 34257193Smuller /* 34357193Smuller * ar_set_wr() 34457193Smuller * special device dependent handling to switch from archive read to 34557193Smuller * archive write on a single volume (an append). VERY device dependent. 34657193Smuller * Note: for tapes, head is already positioned at the place we want to 34757193Smuller * start writing. 34857193Smuller * Return: 34957193Smuller * 0 if all ready to write, -1 otherwise 35057193Smuller */ 35157193Smuller 35257193Smuller #if __STDC__ 35357193Smuller int 35457193Smuller ar_set_wr(void) 35557193Smuller #else 35657193Smuller int 35757193Smuller ar_set_wr() 35857193Smuller #endif 35957193Smuller { 36057193Smuller off_t cpos; 36157193Smuller 36257193Smuller /* 36357193Smuller * Add any device dependent code as required here 36457193Smuller */ 36557193Smuller if (artyp != ISREG) 36657193Smuller return(0); 36757193Smuller /* 368*57535Smuller * Ok we have an archive in a regular file. If we were rewriting a 369*57535Smuller * file, we must get rid of all the stuff after the current offset 370*57535Smuller * (it was not written by pax). 37157193Smuller */ 37257193Smuller if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) || 37357193Smuller (ftruncate(arfd, cpos) < 0)) 37457193Smuller return(-1); 37557193Smuller return(0); 37657193Smuller } 37757193Smuller 37857193Smuller /* 37957193Smuller * ar_app_ok() 38057193Smuller * check if the last volume in the archive allows appends. We cannot check 38157193Smuller * this until we are ready to write since there is no spec that says all 38257193Smuller * volumes in a single archive have to be of the same type... 38357193Smuller * Return: 38457193Smuller * 0 if we can append, -1 otherwise. 38557193Smuller */ 38657193Smuller 38757193Smuller #if __STDC__ 38857193Smuller int 38957193Smuller ar_app_ok(void) 39057193Smuller #else 39157193Smuller int 39257193Smuller ar_app_ok() 39357193Smuller #endif 39457193Smuller { 39557193Smuller if (artyp == ISPIPE) { 39657193Smuller warn(1, "Cannot append to an archive obtained from a pipe."); 39757193Smuller return(-1); 39857193Smuller } 39957193Smuller 40057193Smuller if (!invld_rec) 40157193Smuller return(0); 40257193Smuller warn(1,"Cannot append, device record size %d does not support pax spec", 40357193Smuller rdblksz); 40457193Smuller return(-1); 40557193Smuller } 40657193Smuller 40757193Smuller /* 40857193Smuller * ar_read() 40957193Smuller * read up to a specified number of bytes from the archive into the 41057193Smuller * supplied buffer. When dealing with tapes we may not always be able to 41157193Smuller * read what we want. 41257193Smuller * Return: 41357193Smuller * Number of bytes in buffer. 0 for end of file, -1 for a read error. 41457193Smuller */ 41557193Smuller 41657193Smuller #if __STDC__ 41757193Smuller int 41857193Smuller ar_read(register char *buf, register int cnt) 41957193Smuller #else 42057193Smuller int 42157193Smuller ar_read(buf, cnt) 42257193Smuller register char *buf; 42357193Smuller register int cnt; 42457193Smuller #endif 42557193Smuller { 42657193Smuller register int res = 0; 42757193Smuller 42857193Smuller /* 42957193Smuller * if last i/o was in error, no more reads until reset or new volume 43057193Smuller */ 43157193Smuller if (lstrval <= 0) 43257193Smuller return(lstrval); 43357193Smuller 43457193Smuller /* 43557193Smuller * how we read must be based on device type 43657193Smuller */ 43757193Smuller switch (artyp) { 43857193Smuller case ISTAPE: 43957193Smuller if ((res = read(arfd, buf, cnt)) > 0) { 44057193Smuller /* 44157193Smuller * CAUTION: tape systems may not always return the same 44257193Smuller * sized records so we leave blksz == MAXBLK. The 44357193Smuller * physical record size that a tape drive supports is 44457193Smuller * very hard to determine in a uniform and portable 44557193Smuller * manner. 44657193Smuller */ 44757193Smuller io_ok = 1; 44857193Smuller if (res != rdblksz) { 44957193Smuller /* 45057193Smuller * Record size changed. If this is happens on 451*57535Smuller * any record after the first, we probably have 452*57535Smuller * a tape drive which has a fixed record size 453*57535Smuller * we are getting multiple records in a single 454*57535Smuller * read). Watch out for record blocking that 455*57535Smuller * violates pax spec (must be a multiple of 456*57535Smuller * BLKMULT). 45757193Smuller */ 45857193Smuller rdblksz = res; 45957193Smuller if (rdblksz % BLKMULT) 46057193Smuller invld_rec = 1; 46157193Smuller } 46257193Smuller return(res); 46357193Smuller } 46457193Smuller break; 46557193Smuller case ISREG: 46657193Smuller case ISBLK: 46757193Smuller case ISCHR: 46857193Smuller case ISPIPE: 46957193Smuller default: 47057193Smuller /* 47157193Smuller * Files are so easy to deal with. These other things cannot 47257193Smuller * be trusted at all. So when we are dealing with character 47357193Smuller * devices and pipes we just take what they have ready for us 47457193Smuller * and return. Trying to do anything else with them runs the 47557193Smuller * risk of failure. 47657193Smuller */ 47757193Smuller if ((res = read(arfd, buf, cnt)) > 0) { 47857193Smuller io_ok = 1; 47957193Smuller return(res); 48057193Smuller } 48157193Smuller break; 48257193Smuller } 48357193Smuller 48457193Smuller /* 48557193Smuller * We are in trouble at this point, something is broken... 48657193Smuller */ 48757193Smuller lstrval = res; 48857193Smuller if (res < 0) 48957193Smuller syswarn(1, errno, "Failed read on archive volume %d", arvol); 49057193Smuller else 49157193Smuller warn(0, "End of archive volume %d reached", arvol); 49257193Smuller return(res); 49357193Smuller } 49457193Smuller 49557193Smuller /* 49657193Smuller * ar_write() 49757193Smuller * Write a specified number of bytes in supplied buffer to the archive 49857193Smuller * device so it appears as a single "block". Deals with errors and tries 49957193Smuller * to recover when faced with short writes. 50057193Smuller * Return: 50157193Smuller * Number of bytes written. 0 indicates end of volume reached and with no 50257193Smuller * flaws (as best that can be detected). A -1 indicates an unrecoverable 50357193Smuller * error in the archive occured. 50457193Smuller */ 50557193Smuller 50657193Smuller #if __STDC__ 50757193Smuller int 50857193Smuller ar_write(register char *buf, register int bsz) 50957193Smuller #else 51057193Smuller int 51157193Smuller ar_write(buf, bsz) 51257193Smuller register char *buf; 51357193Smuller register int bsz; 51457193Smuller #endif 51557193Smuller { 51657193Smuller register int res; 51757193Smuller off_t cpos; 51857193Smuller 51957193Smuller /* 52057193Smuller * do not allow pax to create a "bad" archive. Once a write fails on 52157193Smuller * an archive volume prevent further writes to it. 52257193Smuller */ 52357193Smuller if (lstrval <= 0) 52457193Smuller return(lstrval); 52557193Smuller 52657193Smuller if ((res = write(arfd, buf, bsz)) == bsz) { 52757193Smuller io_ok = 1; 52857193Smuller return(bsz); 52957193Smuller } 53057193Smuller 53157193Smuller /* 53257193Smuller * write broke, see what we can do with it. We try to send any partial 533*57535Smuller * writes that may violate pax spec to the next archive volume. 53457193Smuller */ 53557193Smuller if (res < 0) 53657193Smuller lstrval = res; 53757193Smuller else 53857193Smuller lstrval = 0; 53957193Smuller 54057193Smuller switch (artyp) { 54157193Smuller case ISREG: 54257193Smuller if ((res > 0) && (res % BLKMULT)) { 54357193Smuller /* 54457193Smuller * try to fix up partial writes which are not BLKMULT 54557193Smuller * in size by forcing the runt record to next archive 54657193Smuller * volume 54757193Smuller */ 54857193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 54957193Smuller break; 55057193Smuller cpos -= (off_t)res; 55157193Smuller if (ftruncate(arfd, cpos) < 0) 55257193Smuller break; 55357193Smuller res = lstrval = 0; 55457193Smuller break; 55557193Smuller } 55657193Smuller if (res >= 0) 55757193Smuller break; 55857193Smuller /* 55957193Smuller * if file is out of space, handle it like a return of 0 56057193Smuller */ 56157193Smuller if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT)) 56257193Smuller res = lstrval = 0; 56357193Smuller break; 56457193Smuller case ISTAPE: 56557193Smuller case ISCHR: 56657193Smuller case ISBLK: 56757193Smuller if (res >= 0) 56857193Smuller break; 56957193Smuller if (errno == EACCES) { 57057193Smuller warn(0, "Write failed, archive is write protected."); 57157193Smuller res = lstrval = 0; 57257193Smuller return(0); 57357193Smuller } 57457193Smuller /* 57557193Smuller * see if we reached the end of media, if so force a change to 57657193Smuller * the next volume 57757193Smuller */ 57857193Smuller if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO)) 57957193Smuller res = lstrval = 0; 58057193Smuller break; 58157193Smuller case ISPIPE: 58257193Smuller default: 58357193Smuller /* 58457193Smuller * we cannot fix errors to these devices 58557193Smuller */ 58657193Smuller break; 58757193Smuller } 58857193Smuller 58957193Smuller /* 59057193Smuller * Better tell the user the bad news... 591*57535Smuller * if this is a block aligned archive format, we may have a bad archive 592*57535Smuller * if the format wants the header to start at a BLKMULT boundry. While 59357193Smuller * we can deal with the mis-aligned data, it violates spec and other 59457193Smuller * archive readers will likely fail. if the format is not block 595*57535Smuller * aligned, the user may be lucky (and the archive is ok). 59657193Smuller */ 59757193Smuller if (res >= 0) 59857193Smuller io_ok = 1; 59957193Smuller if (res == 0) 60057193Smuller warn(0, "End of archive volume %d reached", arvol); 60157193Smuller else if (res < 0) 60257193Smuller syswarn(1, errno, "Failed write to archive volume: %d", arvol); 60357193Smuller else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0)) 60457193Smuller warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED"); 60557193Smuller else 60657193Smuller warn(1,"WARNING: partial archive write. Archive IS FLAWED"); 60757193Smuller return(res); 60857193Smuller } 60957193Smuller 61057193Smuller /* 61157193Smuller * ar_rdsync() 61257193Smuller * Try to move past a bad spot on a flawed archive as needed to continue 61357193Smuller * I/O. Clears error flags to allow I/O to continue. 61457193Smuller * Return: 61557193Smuller * 0 when ok to try i/o again, -1 otherwise. 61657193Smuller */ 61757193Smuller 61857193Smuller #if __STDC__ 61957193Smuller int 62057193Smuller ar_rdsync(void) 62157193Smuller #else 62257193Smuller int 62357193Smuller ar_rdsync() 62457193Smuller #endif 62557193Smuller { 62657193Smuller long fsbz; 62757193Smuller off_t cpos; 62857193Smuller off_t mpos; 62957193Smuller struct mtop mb; 63057193Smuller 63157193Smuller /* 63257193Smuller * Fail resync attempts at user request (done) or this is going to be 63357193Smuller * an update/append to a existing archive. if last i/o hit media end, 63457193Smuller * we need to go to the next volume not try a resync 63557193Smuller */ 63657193Smuller if ((done > 0) || (lstrval == 0)) 63757193Smuller return(-1); 63857193Smuller 63957193Smuller if ((act == APPND) || (act == ARCHIVE)) { 64057193Smuller warn(1, "Cannot allow updates to an archive with flaws."); 64157193Smuller return(-1); 64257193Smuller } 64357193Smuller if (io_ok) 64457193Smuller did_io = 1; 64557193Smuller 64657193Smuller switch(artyp) { 64757193Smuller case ISTAPE: 64857193Smuller /* 64957193Smuller * if the last i/o was a successful data transfer, we assume 65057193Smuller * the fault is just a bad record on the tape that we are now 65157193Smuller * past. If we did not get any data since the last resync try 65257193Smuller * to move the tape foward one PHYSICAL record past any 65357193Smuller * damaged tape section. Some tape drives are stubborn and need 65457193Smuller * to be pushed. 65557193Smuller */ 65657193Smuller if (io_ok) { 65757193Smuller io_ok = 0; 65857193Smuller lstrval = 1; 65957193Smuller break; 66057193Smuller } 66157193Smuller mb.mt_op = MTFSR; 66257193Smuller mb.mt_count = 1; 66357193Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) 66457193Smuller break; 66557193Smuller lstrval = 1; 66657193Smuller break; 66757193Smuller case ISREG: 66857193Smuller case ISCHR: 66957193Smuller case ISBLK: 67057193Smuller /* 67157193Smuller * try to step over the bad part of the device. 67257193Smuller */ 67357193Smuller io_ok = 0; 67457193Smuller if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) 67557193Smuller fsbz = BLKMULT; 67657193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 67757193Smuller break; 67857193Smuller mpos = fsbz - (cpos % (off_t)fsbz); 67957193Smuller if (lseek(arfd, mpos, SEEK_CUR) < 0) 68057193Smuller break; 68157193Smuller lstrval = 1; 68257193Smuller break; 68357193Smuller case ISPIPE: 68457193Smuller default: 68557193Smuller /* 68657193Smuller * cannot recover on these archive device types 68757193Smuller */ 68857193Smuller io_ok = 0; 68957193Smuller break; 69057193Smuller } 69157193Smuller if (lstrval <= 0) { 692*57535Smuller warn(1, "Unable to recover from an archive read failure."); 69357193Smuller return(-1); 69457193Smuller } 69557193Smuller warn(0, "Attempting to recover from an archive read failure."); 69657193Smuller return(0); 69757193Smuller } 69857193Smuller 69957193Smuller /* 70057193Smuller * ar_fow() 70157193Smuller * Move the I/O position within the archive foward the specified number of 70257193Smuller * bytes as supported by the device. If we cannot move the requested 70357193Smuller * number of bytes, return the actual number of bytes moved in skipped. 70457193Smuller * Return: 70557193Smuller * 0 if moved the requested distance, -1 on complete failure, 1 on 70657193Smuller * partial move (the amount moved is in skipped) 70757193Smuller */ 70857193Smuller 70957193Smuller #if __STDC__ 71057193Smuller int 71157193Smuller ar_fow(off_t sksz, off_t *skipped) 71257193Smuller #else 71357193Smuller int 71457193Smuller ar_fow(sksz, skipped) 71557193Smuller off_t sksz; 71657193Smuller off_t *skipped; 71757193Smuller #endif 71857193Smuller { 71957193Smuller off_t cpos; 72057193Smuller off_t mpos; 72157193Smuller 72257193Smuller *skipped = 0; 72357193Smuller if (sksz <= 0) 72457193Smuller return(0); 72557193Smuller 72657193Smuller /* 72757193Smuller * we cannot move foward at EOF or error 72857193Smuller */ 72957193Smuller if (lstrval <= 0) 73057193Smuller return(lstrval); 73157193Smuller 73257193Smuller /* 73357193Smuller * Safer to read forward on devices where it is hard to find the end of 73457193Smuller * the media without reading to it. With tapes we cannot be sure of the 73557193Smuller * number of physical blocks to skip (we do not know physical block 73657193Smuller * size at this point), so we must only read foward on tapes! 73757193Smuller */ 73857193Smuller if (artyp != ISREG) 73957193Smuller return(0); 74057193Smuller 74157193Smuller /* 74257193Smuller * figure out where we are in the archive 74357193Smuller */ 74457193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) { 74557193Smuller /* 74657193Smuller * we can be asked to move farther than there are bytes in this 74757193Smuller * volume, if so, just go to file end and let normal buf_fill() 74857193Smuller * deal with the end of file (it will go to next volume by 74957193Smuller * itself) 75057193Smuller */ 75157193Smuller if ((mpos = cpos + sksz) > arsb.st_size) { 75257193Smuller *skipped = arsb.st_size - cpos; 75357193Smuller mpos = arsb.st_size; 75457193Smuller } else 75557193Smuller *skipped = sksz; 75657193Smuller if (lseek(arfd, mpos, SEEK_SET) >= 0) 75757193Smuller return(0); 75857193Smuller } 75957193Smuller syswarn(1, errno, "Foward positioning operation on archive failed"); 76057193Smuller lstrval = -1; 76157193Smuller return(-1); 76257193Smuller } 76357193Smuller 76457193Smuller /* 76557193Smuller * ar_rev() 76657193Smuller * move the i/o position within the archive backwards the specified byte 76757193Smuller * count as supported by the device. With tapes drives we RESET rdblksz to 76857193Smuller * the PHYSICAL blocksize. 76957193Smuller * NOTE: We should only be called to move backwards so we can rewrite the 77057193Smuller * last records (the trailer) of an archive (APPEND). 77157193Smuller * Return: 77257193Smuller * 0 if moved the requested distance, -1 on complete failure 77357193Smuller */ 77457193Smuller 77557193Smuller #if __STDC__ 77657193Smuller int 77757193Smuller ar_rev(off_t sksz) 77857193Smuller #else 77957193Smuller int 78057193Smuller ar_rev(sksz) 78157193Smuller off_t sksz; 78257193Smuller #endif 78357193Smuller { 78457193Smuller off_t cpos; 78557193Smuller struct mtop mb; 78657193Smuller 78757193Smuller if (sksz <= 0) 78857193Smuller return(0); 78957193Smuller 79057193Smuller /* 79157193Smuller * make sure we do not have a flawed archive 79257193Smuller */ 79357193Smuller if (lstrval < 0) 79457193Smuller return(lstrval); 79557193Smuller 79657193Smuller switch(artyp) { 79757193Smuller case ISPIPE: 79857193Smuller /* 79957193Smuller * cannot go backwards on these critters 80057193Smuller */ 80157193Smuller break; 80257193Smuller case ISREG: 80357193Smuller case ISBLK: 80457193Smuller case ISCHR: 80557193Smuller default: 80657193Smuller /* 80757193Smuller * For things other than files, backwards movement has a very 80857193Smuller * high probability of failure as we really do not know the 80957193Smuller * true attributes of the device we are talking to (the device 81057193Smuller * may not even have the ability to lseek() in any direction). 81157193Smuller * first we figure out where we are in the archive 81257193Smuller */ 81357193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 81457193Smuller break; 81557193Smuller 81657193Smuller /* 81757193Smuller * we may try to go backwards past the start when the archive 81857193Smuller * is only a single record. If this hapens and we are on a 81957193Smuller * multi volume archive, we need to go to the end of the 82057193Smuller * previous volume and continue our movement backwards from 82157193Smuller * there. (This is really hard to do and is NOT IMPLEMENTED) 82257193Smuller */ 82357193Smuller if ((cpos -= sksz) < (off_t)0L) { 82457193Smuller if (arvol > 1) { 82557193Smuller warn(1,"End of archive is on previous volume."); 82657193Smuller lstrval = -1; 82757193Smuller return(-1); 82857193Smuller } 82957193Smuller cpos = (off_t)0L; 83057193Smuller } 83157193Smuller if (lseek(arfd, cpos, SEEK_SET) < 0) 83257193Smuller break; 83357193Smuller lstrval = 1; 83457193Smuller return(0); 83557193Smuller case ISTAPE: 83657193Smuller /* 83757193Smuller * Calculate and move the proper number of PHYSICAL tape 83857193Smuller * records. If the sksz is not an even multiple of the physical 83957193Smuller * tape size, we cannot do the move (this should never happen). 84057193Smuller * (We also cannot handler trailers spread over two vols). 84157193Smuller */ 84257193Smuller if (get_phys() < 0) { 84357193Smuller warn(1, "Cannot determine archive tape blocksize."); 84457193Smuller break; 84557193Smuller } 84657193Smuller 84757193Smuller if (sksz % phyblk) { 84857193Smuller warn(1,"Tape drive cannot backspace %d bytes (%d phys)", 84957193Smuller sksz, phyblk); 85057193Smuller lstrval = -1; 85157193Smuller return(-1); 85257193Smuller } 85357193Smuller 85457193Smuller mb.mt_op = MTBSR; 85557193Smuller mb.mt_count = sksz/phyblk; 85657193Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) 85757193Smuller break; 85857193Smuller 85957193Smuller /* 86057193Smuller * reset rdblksz to be the device physical blocksize. 86157193Smuller */ 86257193Smuller rdblksz = phyblk; 86357193Smuller lstrval = 1; 86457193Smuller return(0); 86557193Smuller } 86657193Smuller syswarn(1, errno, "Reverse positioning operation on archive failed"); 86757193Smuller lstrval = -1; 86857193Smuller return(-1); 86957193Smuller } 87057193Smuller 87157193Smuller /* 87257193Smuller * get_phys() 87357193Smuller * Determine the physical block size on a tape drive. Should only be 874*57535Smuller * when at EOF. Tape drives are so inconsistant, while finding true record 875*57535Smuller * size should be a trival thing to figure out, it really is difficult and 876*57535Smuller * very likely to fail. 87757193Smuller * Return: 87857193Smuller * 0 if ok, -1 otherwise 87957193Smuller */ 88057193Smuller 88157193Smuller #if __STDC__ 88257193Smuller static int 88357193Smuller get_phys(void) 88457193Smuller #else 88557193Smuller static int 88657193Smuller get_phys() 88757193Smuller #endif 88857193Smuller { 889*57535Smuller register int res; 890*57535Smuller struct mtop mb; 89157193Smuller char scbuf1[MAXBLK]; 89257193Smuller char scbuf2[MAXBLK]; 89357193Smuller 89457193Smuller /* 895*57535Smuller * We backspace one record and read foward. The read should tell us the 896*57535Smuller * true physical size. We can only use this technique when we are at 897*57535Smuller * tape EOF (so the MTBSR will leave just a SINGLE PHYSICAL record 898*57535Smuller * between the head and the end of the tape file; the max we can then 899*57535Smuller * read should be just ONE physical record). Since we may be called 900*57535Smuller * more than once, only the first phyblk detection will be used. 901*57535Smuller */ 90257193Smuller if (phyblk > 0) 90357193Smuller return(0); 90457193Smuller 90557193Smuller mb.mt_op = MTBSR; 90657193Smuller mb.mt_count = 1; 90757193Smuller if ((ioctl(arfd, MTIOCTOP, &mb) < 0) || 908*57535Smuller ((phyblk = read(arfd, scbuf1, sizeof(scbuf1))) <= 0)) { 90957193Smuller return(-1); 910*57535Smuller } 91157193Smuller 91257193Smuller /* 913*57535Smuller * We must be careful, we may not have been called with the tape head 914*57535Smuller * at the end of the tape. We expect if we read again we will get the 915*57535Smuller * true blocksize. (We expect the true size on the second read because 916*57535Smuller * by pax spec the trailer is always in the last record, and we are 917*57535Smuller * only called after the trailer was seen. If this is not true, the 918*57535Smuller * archive is flawed and we will return a failure indication). After 919*57535Smuller * the second read we must adjust the head position so it is at the 920*57535Smuller * same place it was when we are called. We also check for consistancy, 921*57535Smuller * if we cannot repeat we return a failure. 92257193Smuller */ 92357193Smuller if ((ioctl(arfd, MTIOCTOP, &mb) < 0) || 924*57535Smuller ((res = read(arfd, scbuf2, sizeof(scbuf2))) <= 0)) 92557193Smuller return(-1); 926*57535Smuller 927*57535Smuller /* 928*57535Smuller * If we get a bigger size on the second read or the first read is not 929*57535Smuller * a multiple of the second read, we better not chance an append. 930*57535Smuller */ 931*57535Smuller if ((res > phyblk) || (phyblk % res)) 932*57535Smuller return(-1); 933*57535Smuller 934*57535Smuller /* 935*57535Smuller * if both reads are the same size and the data is consistant we can 936*57535Smuller * go on with the append 937*57535Smuller */ 938*57535Smuller if (res == phyblk) { 939*57535Smuller if (bcmp(scbuf1, scbuf2, phyblk) != 0) 940*57535Smuller return(-1); 941*57535Smuller return(0); 942*57535Smuller } 943*57535Smuller 944*57535Smuller /* 945*57535Smuller * We got two different block sizes. We were not at the tape EOF. 946*57535Smuller * So we try one more time, if the result is not consistant we abort. 947*57535Smuller */ 948*57535Smuller if ((ioctl(arfd, MTIOCTOP, &mb) < 0) || 949*57535Smuller (read(arfd, scbuf1, sizeof(scbuf1)) != res) || 950*57535Smuller (bcmp(scbuf1, scbuf2, res) != 0)) 951*57535Smuller return(-1); 952*57535Smuller 953*57535Smuller /* 954*57535Smuller * Ok, we assume the physical block size is in res. We need to adjust 955*57535Smuller * head position backwards based on the what we got on the first read. 956*57535Smuller * (must leave the head at the same place it was when we were called). 957*57535Smuller */ 958*57535Smuller mb.mt_count = (phyblk - res)/res; 959*57535Smuller phyblk = res; 960*57535Smuller if ((mb.mt_count == 0) || (ioctl(arfd, MTIOCTOP, &mb) < 0)) 961*57535Smuller return(-1); 96257193Smuller return(0); 96357193Smuller } 96457193Smuller 96557193Smuller /* 96657193Smuller * ar_next() 967*57535Smuller * prompts the user for the next volume in this archive. For some devices 968*57535Smuller * we may allow the media to be changed. Otherwise a new archive is 969*57535Smuller * prompted for. By pax spec, if there is no controlling tty or an eof is 970*57535Smuller * read on tty input, we must quit pax. 97157193Smuller * Return: 97257193Smuller * 0 when ready to continue, -1 when all done 97357193Smuller */ 97457193Smuller 97557193Smuller #if __STDC__ 97657193Smuller int 97757193Smuller ar_next(void) 97857193Smuller #else 97957193Smuller int 98057193Smuller ar_next() 98157193Smuller #endif 98257193Smuller { 98357193Smuller char buf[PAXPATHLEN+2]; 98457193Smuller static int freeit = 0; 98557193Smuller sigset_t o_mask; 98657193Smuller 98757193Smuller /* 988*57535Smuller * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so 98957193Smuller * things like writing EOF etc will be done) (Watch out ar_close() can 990*57535Smuller * also be called via a signal handler, so we must prevent a race. 99157193Smuller */ 99257193Smuller if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0) 993*57535Smuller syswarn(0, errno, "Unable to set signal mask"); 99457193Smuller ar_close(); 99557193Smuller if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0) 996*57535Smuller syswarn(0, errno, "Unable to restore signal mask"); 99757193Smuller 99857193Smuller if (done) 99957193Smuller return(-1); 100057193Smuller 100157193Smuller tty_prnt("\nATTENTION! Pax archive volume change required.\n"); 100257193Smuller 100357193Smuller /* 100457193Smuller * if i/o is on stdin or stdout, we cannot reopen it (we do not know 1005*57535Smuller * the name), the user will be forced to type it in. 100657193Smuller */ 100757193Smuller if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG) 100857193Smuller && (artyp != ISPIPE)) { 100957193Smuller if (artyp == ISTAPE) { 101057193Smuller tty_prnt("%s ready for archive tape volume: %d\n", 101157193Smuller arcname, arvol); 101257193Smuller tty_prnt("Load the NEXT TAPE on the tape drive"); 101357193Smuller } else { 101457193Smuller tty_prnt("%s ready for archive volume: %d\n", 101557193Smuller arcname, arvol); 101657193Smuller tty_prnt("Load the NEXT STORAGE MEDIA (if required)"); 101757193Smuller } 101857193Smuller 101957193Smuller if ((act == ARCHIVE) || (act == APPND)) 102057193Smuller tty_prnt(" and make sure it is WRITE ENABLED.\n"); 102157193Smuller else 102257193Smuller tty_prnt("\n"); 102357193Smuller 102457193Smuller for(;;) { 102557193Smuller tty_prnt("Type \"y\" to continue, \".\" to quit pax,"); 102657193Smuller tty_prnt(" or \"s\" to switch to new device.\nIf you"); 102757193Smuller tty_prnt(" cannot change storage media, type \"s\"\n"); 102857193Smuller tty_prnt("Is the device ready and online? > "); 102957193Smuller 103057193Smuller if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){ 103157193Smuller done = 1; 103257193Smuller lstrval = -1; 103357193Smuller tty_prnt("Quitting pax!\n"); 103457193Smuller vfpart = 0; 103557193Smuller return(-1); 103657193Smuller } 103757193Smuller 103857193Smuller if ((buf[0] == '\0') || (buf[1] != '\0')) { 103957193Smuller tty_prnt("%s unknown command, try again\n",buf); 104057193Smuller continue; 104157193Smuller } 104257193Smuller 104357193Smuller switch (buf[0]) { 104457193Smuller case 'y': 104557193Smuller case 'Y': 104657193Smuller /* 104757193Smuller * we are to continue with the same device 104857193Smuller */ 104957193Smuller if (ar_open(arcname) >= 0) 105057193Smuller return(0); 105157193Smuller tty_prnt("Cannot re-open %s, try again\n", 105257193Smuller arcname); 105357193Smuller continue; 105457193Smuller case 's': 105557193Smuller case 'S': 105657193Smuller /* 105757193Smuller * user wants to open a different device 105857193Smuller */ 105957193Smuller tty_prnt("Switching to a different archive\n"); 106057193Smuller break; 106157193Smuller default: 106257193Smuller tty_prnt("%s unknown command, try again\n",buf); 106357193Smuller continue; 106457193Smuller } 106557193Smuller break; 106657193Smuller } 106757193Smuller } else 106857193Smuller tty_prnt("Ready for archive volume: %d\n", arvol); 106957193Smuller 107057193Smuller /* 107157193Smuller * have to go to a different archive 107257193Smuller */ 107357193Smuller for (;;) { 107457193Smuller tty_prnt("Input archive name or \".\" to quit pax.\n"); 107557193Smuller tty_prnt("Archive name > "); 107657193Smuller 107757193Smuller if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) { 107857193Smuller done = 1; 107957193Smuller lstrval = -1; 108057193Smuller tty_prnt("Quitting pax!\n"); 108157193Smuller vfpart = 0; 108257193Smuller return(-1); 108357193Smuller } 108457193Smuller if (buf[0] == '\0') { 108557193Smuller tty_prnt("Empty file name, try again\n"); 108657193Smuller continue; 108757193Smuller } 108857193Smuller if (!strcmp(buf, "..")) { 108957193Smuller tty_prnt("Illegal file name: .. try again\n"); 109057193Smuller continue; 109157193Smuller } 109257193Smuller if (strlen(buf) > PAXPATHLEN) { 109357193Smuller tty_prnt("File name too long, try again\n"); 109457193Smuller continue; 109557193Smuller } 109657193Smuller 109757193Smuller /* 109857193Smuller * try to open new archive 109957193Smuller */ 110057193Smuller if (ar_open(buf) >= 0) { 110157193Smuller if (freeit) { 110257193Smuller (void)free(arcname); 110357193Smuller freeit = 0; 110457193Smuller } 110557193Smuller if ((arcname = strdup(buf)) == NULL) { 110657193Smuller done = 1; 110757193Smuller lstrval = -1; 1108*57535Smuller warn(0, "Cannot save archive name."); 110957193Smuller return(-1); 111057193Smuller } 111157193Smuller freeit = 1; 111257193Smuller break; 111357193Smuller } 111457193Smuller tty_prnt("Cannot open %s, try again\n", buf); 111557193Smuller continue; 111657193Smuller } 111757193Smuller return(0); 111857193Smuller } 1119