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*58651Smuller static char sccsid[] = "@(#)ar_io.c 1.6 (Berkeley) 03/12/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 /* 3457535Smuller * 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 */ 4457584Smuller static int artyp = ISREG; /* 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 */ 4857535Smuller 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 */ 5257578Smuller static int wr_trail = 1; /* trailer was rewritten in append */ 5357584Smuller static int can_unlnk = 0; /* do we unlink null archives? */ 5457193Smuller char *arcname; /* printable name of archive */ 5557193Smuller 5657193Smuller static int get_phys __P((void)); 5757193Smuller extern sigset_t s_mask; 5857193Smuller 5957193Smuller /* 6057193Smuller * ar_open() 6157193Smuller * Opens the next archive volume. Determines the type of the device and 6257193Smuller * sets up block sizes as required by the archive device and the format. 6357193Smuller * Note: we may be called with name == NULL on the first open only. 6457193Smuller * Return: 6557193Smuller * -1 on failure, 0 otherwise 6657193Smuller */ 6757193Smuller 6857193Smuller #if __STDC__ 6957193Smuller int 7057193Smuller ar_open(char *name) 7157193Smuller #else 7257193Smuller int 7357193Smuller ar_open(name) 7457193Smuller char *name; 7557193Smuller #endif 7657193Smuller { 7757193Smuller struct mtget mb; 7857193Smuller 7957193Smuller if (arfd != -1) 8057193Smuller (void)close(arfd); 8157193Smuller arfd = -1; 8257794Smuller can_unlnk = did_io = io_ok = invld_rec = 0; 8357584Smuller artyp = ISREG; 8457193Smuller flcnt = 0; 8557193Smuller 8657193Smuller /* 8757193Smuller * open based on overall operation mode 8857193Smuller */ 8957193Smuller switch (act) { 9057193Smuller case LIST: 9157193Smuller case EXTRACT: 9257193Smuller if (name == NULL) { 9357193Smuller arfd = STDIN_FILENO; 9457193Smuller arcname = STDN; 9557193Smuller } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0) 9657535Smuller syswarn(0, errno, "Failed open to read on %s", name); 9757193Smuller break; 9857193Smuller case ARCHIVE: 9957193Smuller if (name == NULL) { 10057193Smuller arfd = STDOUT_FILENO; 10157193Smuller arcname = STDO; 10257193Smuller } else if ((arfd = open(name, AR_MODE, DMOD)) < 0) 10357535Smuller syswarn(0, errno, "Failed open to write on %s", name); 10457584Smuller else 10557584Smuller can_unlnk = 1; 10657193Smuller break; 10757193Smuller case APPND: 10857193Smuller if (name == NULL) { 10957193Smuller arfd = STDOUT_FILENO; 11057193Smuller arcname = STDO; 11157193Smuller } else if ((arfd = open(name, APP_MODE, DMOD)) < 0) 11257535Smuller syswarn(0, errno, "Failed open to read/write on %s", 11357193Smuller name); 11457193Smuller break; 11557193Smuller case COPY: 11657193Smuller /* 11757193Smuller * arfd not used in COPY mode 11857193Smuller */ 11957193Smuller arcname = "<NONE>"; 12057193Smuller lstrval = 1; 12157193Smuller return(0); 12257193Smuller } 12357193Smuller if (arfd < 0) 12457193Smuller return(-1); 12557193Smuller 12657193Smuller /* 12757193Smuller * set up is based on device type 12857193Smuller */ 12957193Smuller if (fstat(arfd, &arsb) < 0) { 13057535Smuller syswarn(0, errno, "Failed stat on %s", arcname); 13157584Smuller (void)close(arfd); 13257584Smuller arfd = -1; 13357584Smuller can_unlnk = 0; 13457193Smuller return(-1); 13557193Smuller } 13657193Smuller if (S_ISDIR(arsb.st_mode)) { 13757535Smuller warn(0, "Cannot write an archive on top of a directory %s", 13857193Smuller arcname); 13957584Smuller (void)close(arfd); 14057584Smuller arfd = -1; 14157584Smuller can_unlnk = 0; 14257193Smuller return(-1); 14357193Smuller } 14457584Smuller 14557193Smuller if (S_ISCHR(arsb.st_mode)) 14657193Smuller artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE; 14757193Smuller else if (S_ISBLK(arsb.st_mode)) 14857193Smuller artyp = ISBLK; 14957193Smuller else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE)) 15057193Smuller artyp = ISPIPE; 15157193Smuller else 15257193Smuller artyp = ISREG; 15357193Smuller 15457193Smuller /* 15557584Smuller * make sure we beyond any doubt that we only can unlink regular files 15657584Smuller * we created 15757584Smuller */ 15857584Smuller if (artyp != ISREG) 15957584Smuller can_unlnk = 0; 16057584Smuller /* 16157535Smuller * if we are writing, we are done 16257193Smuller */ 16357193Smuller if (act == ARCHIVE) { 16457193Smuller blksz = rdblksz = wrblksz; 16557193Smuller lstrval = 1; 16657193Smuller return(0); 16757193Smuller } 16857193Smuller 16957193Smuller /* 17057193Smuller * set default blksz on read. APPNDs writes rdblksz on the last volume 17157193Smuller * On all new archive volumes, we shift to wrblksz (if the user 17257193Smuller * specified one, otherwize we will continue to use rdblksz). We 17357193Smuller * must to set blocksize based on what kind of device the archive is 17457193Smuller * stored. 17557193Smuller */ 17657193Smuller switch(artyp) { 17757193Smuller case ISTAPE: 17857193Smuller /* 17957193Smuller * Tape drives come in at least two flavors. Those that support 18057193Smuller * variable sized records and those that have fixed sized 18157193Smuller * records. They must be treated differently. For tape drives 18257193Smuller * that support variable sized records, we must make large 18357193Smuller * reads to make sure we get the entire record, otherwise we 18457193Smuller * will just get the first part of the record (up to size we 18557193Smuller * asked). Tapes with fixed sized records may or may not return 18657193Smuller * multiple records in a single read. We really do not care 18757193Smuller * what the physical record size is UNLESS we are going to 18857193Smuller * append. (We will need the physical block size to rewrite 18957193Smuller * the trailer). Only when we are appending do we go to the 19057535Smuller * effort to figure out the true PHYSICAL record size. 19157193Smuller */ 19257193Smuller blksz = rdblksz = MAXBLK; 19357193Smuller break; 19457193Smuller case ISPIPE: 19557193Smuller case ISBLK: 19657193Smuller case ISCHR: 19757193Smuller /* 19857193Smuller * Blocksize is not a major issue with these devices (but must 19957193Smuller * be kept a multiple of 512). If the user specified a write 20057193Smuller * block size, we use that to read. Under append, we must 20157193Smuller * always keep blksz == rdblksz. Otherwise we go ahead and use 20257193Smuller * the device optimal blocksize as (and if) returned by stat 20357193Smuller * and if it is within pax specs. 20457193Smuller */ 20557193Smuller if ((act == APPND) && wrblksz) { 20657193Smuller blksz = rdblksz = wrblksz; 20757193Smuller break; 20857193Smuller } 20957193Smuller 21057193Smuller if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) && 21157193Smuller ((arsb.st_blksize % BLKMULT) == 0)) 21257193Smuller rdblksz = arsb.st_blksize; 21357193Smuller else 21457193Smuller rdblksz = DEVBLK; 21557193Smuller /* 21657193Smuller * For performance go for large reads when we can without harm 21757193Smuller */ 21857193Smuller if ((act == APPND) || (artyp == ISCHR)) 21957193Smuller blksz = rdblksz; 22057193Smuller else 22157193Smuller blksz = MAXBLK; 22257193Smuller break; 22357193Smuller case ISREG: 22457193Smuller /* 22557193Smuller * if the user specified wrblksz works, use it. Under appends 22657193Smuller * we must always keep blksz == rdblksz 22757193Smuller */ 22857193Smuller if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){ 22957193Smuller blksz = rdblksz = wrblksz; 23057193Smuller break; 23157193Smuller } 23257193Smuller /* 23357193Smuller * See if we can find the blocking factor from the file size 23457193Smuller */ 23557193Smuller for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT) 23657193Smuller if ((arsb.st_size % rdblksz) == 0) 23757193Smuller break; 23857193Smuller /* 23957193Smuller * When we cannont find a match, we may have a flawed archive. 24057193Smuller */ 24157193Smuller if (rdblksz <= 0) 24257193Smuller rdblksz = FILEBLK; 24357193Smuller /* 24457193Smuller * for performance go for large reads when we can 24557193Smuller */ 24657193Smuller if (act == APPND) 24757193Smuller blksz = rdblksz; 24857193Smuller else 24957193Smuller blksz = MAXBLK; 25057193Smuller break; 25157193Smuller default: 25257193Smuller /* 25357193Smuller * should never happen, worse case, slow... 25457193Smuller */ 25557193Smuller blksz = rdblksz = BLKMULT; 25657193Smuller break; 25757193Smuller } 25857193Smuller lstrval = 1; 25957193Smuller return(0); 26057193Smuller } 26157193Smuller 26257193Smuller /* 26357193Smuller * ar_close() 26457193Smuller * closes archive device, increments volume number, and prints i/o summary 26557193Smuller */ 26657193Smuller #if __STDC__ 26757193Smuller void 26857193Smuller ar_close(void) 26957193Smuller #else 27057193Smuller void 27157193Smuller ar_close() 27257193Smuller #endif 27357193Smuller { 27457193Smuller FILE *outf; 27557193Smuller 27657578Smuller if (arfd < 0) { 27757578Smuller did_io = io_ok = flcnt = 0; 27857578Smuller return; 27957578Smuller } 28057578Smuller 28157535Smuller if (act == LIST) 28257535Smuller outf = stdout; 28357535Smuller else 28457535Smuller outf = stderr; 28557535Smuller 28657535Smuller /* 28757535Smuller * Close archive file. This may take a LONG while on tapes (we may be 28857535Smuller * forced to wait for the rewind to complete) so tell the user what is 28957535Smuller * going on (this avoids the user hitting control-c thinking pax is 29057535Smuller * broken). 29157535Smuller */ 29257578Smuller if (vflag && (artyp == ISTAPE)) { 29357578Smuller if (vfpart) 29457535Smuller (void)putc('\n', outf); 29557535Smuller (void)fputs("pax: Waiting for tape drive close to complete...", 29657535Smuller outf); 29757535Smuller (void)fflush(outf); 29857535Smuller } 29957535Smuller 30057584Smuller /* 30157584Smuller * if nothing was written to the archive (and we created it), we remove 30257584Smuller * it 30357584Smuller */ 30457584Smuller if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) && 30557584Smuller (arsb.st_size == 0)) { 30657584Smuller (void)unlink(arcname); 30757584Smuller can_unlnk = 0; 30857584Smuller } 30957584Smuller 31057193Smuller (void)close(arfd); 31157535Smuller 31257578Smuller if (vflag && (artyp == ISTAPE)) { 31357535Smuller (void)fputs("done.\n", outf); 31457578Smuller vfpart = 0; 31557535Smuller (void)fflush(outf); 31657535Smuller } 31757193Smuller arfd = -1; 31857535Smuller 31957193Smuller if (!io_ok && !did_io) { 32057193Smuller flcnt = 0; 32157193Smuller return; 32257193Smuller } 32357193Smuller did_io = io_ok = 0; 32457193Smuller 32557193Smuller /* 32657193Smuller * The volume number is only increased when the last device has data 32757535Smuller * and we have already determined the archive format. 32857193Smuller */ 32957535Smuller if (frmt != NULL) 33057535Smuller ++arvol; 33157535Smuller 33257193Smuller if (!vflag) { 33357193Smuller flcnt = 0; 33457193Smuller return; 33557193Smuller } 33657193Smuller 33757193Smuller /* 33857193Smuller * Print out a summary of I/O for this archive volume. 33957193Smuller */ 34057193Smuller if (vfpart) { 34157193Smuller (void)putc('\n', outf); 34257193Smuller vfpart = 0; 34357193Smuller } 34457193Smuller 34557535Smuller /* 34657535Smuller * If we have not determined the format yet, we just say how many bytes 34757535Smuller * we have skipped over looking for a header to id. there is no way we 34857535Smuller * could have written anything yet. 34957535Smuller */ 35057535Smuller if (frmt == NULL) { 35157535Smuller # ifdef NET2_STAT 35257535Smuller (void)fprintf(outf, "pax: unknown format, %lu bytes skipped.\n", 35357535Smuller # else 35457535Smuller (void)fprintf(outf, "pax: unknown format, %qu bytes skipped.\n", 35557535Smuller # endif 35657535Smuller rdcnt); 35757535Smuller (void)fflush(outf); 35857535Smuller flcnt = 0; 35957535Smuller return; 36057535Smuller } 36157535Smuller 36257193Smuller (void)fprintf(outf, 36357193Smuller # ifdef NET2_STAT 36457535Smuller "pax: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n", 36557193Smuller # else 36657535Smuller "pax: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n", 36757193Smuller # endif 36857193Smuller frmt->name, arvol-1, flcnt, rdcnt, wrcnt); 36957193Smuller (void)fflush(outf); 37057193Smuller flcnt = 0; 37157193Smuller } 37257193Smuller 37357193Smuller /* 374*58651Smuller * ar_drain() 375*58651Smuller * drain any archive format independent padding from an archive read 376*58651Smuller * from a socket or a pipe. This is to prevent the process on the 377*58651Smuller * other side of the pipe from getting a SIGPIPE (pax will stop 378*58651Smuller * reading an archive once a format dependent trailer is detected). 379*58651Smuller */ 380*58651Smuller #if __STDC__ 381*58651Smuller void 382*58651Smuller ar_drain(void) 383*58651Smuller #else 384*58651Smuller void 385*58651Smuller ar_drain() 386*58651Smuller #endif 387*58651Smuller { 388*58651Smuller register int res; 389*58651Smuller char drbuf[MAXBLK]; 390*58651Smuller 391*58651Smuller /* 392*58651Smuller * we only drain from a pipe/socket. Other devices can be closed 393*58651Smuller * without reading up to end of file. We sure hope that pipe is closed 394*58651Smuller * on the other side so we will get an EOF. 395*58651Smuller */ 396*58651Smuller if ((artyp != ISPIPE) || (lstrval <= 0)) 397*58651Smuller return; 398*58651Smuller 399*58651Smuller /* 400*58651Smuller * keep reading until pipe is drained 401*58651Smuller */ 402*58651Smuller while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0) 403*58651Smuller ; 404*58651Smuller lstrval = res; 405*58651Smuller } 406*58651Smuller 407*58651Smuller /* 40857193Smuller * ar_set_wr() 40957578Smuller * Set up device right before switching from read to write in an append. 41057578Smuller * device dependent code (if required) to do this should be added here. 41157578Smuller * For all archive devices we are already positioned at the place we want 41257578Smuller * to start writing when this routine is called. 41357193Smuller * Return: 41457193Smuller * 0 if all ready to write, -1 otherwise 41557193Smuller */ 41657193Smuller 41757193Smuller #if __STDC__ 41857193Smuller int 41957193Smuller ar_set_wr(void) 42057193Smuller #else 42157193Smuller int 42257193Smuller ar_set_wr() 42357193Smuller #endif 42457193Smuller { 42557193Smuller off_t cpos; 42657193Smuller 42757578Smuller /* 42857578Smuller * we must make sure the trailer is rewritten on append, ar_next() 42957578Smuller * will stop us if the archive containing the trailer was not written 43057578Smuller */ 43157578Smuller wr_trail = 0; 43257578Smuller 43357193Smuller /* 43457193Smuller * Add any device dependent code as required here 43557193Smuller */ 43657193Smuller if (artyp != ISREG) 43757193Smuller return(0); 43857193Smuller /* 43957535Smuller * Ok we have an archive in a regular file. If we were rewriting a 44057535Smuller * file, we must get rid of all the stuff after the current offset 44157535Smuller * (it was not written by pax). 44257193Smuller */ 44357193Smuller if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) || 44457578Smuller (ftruncate(arfd, cpos) < 0)) { 44557578Smuller syswarn(1, errno, "Unable to truncate archive file"); 44657193Smuller return(-1); 44757578Smuller } 44857193Smuller return(0); 44957193Smuller } 45057193Smuller 45157193Smuller /* 45257193Smuller * ar_app_ok() 45357193Smuller * check if the last volume in the archive allows appends. We cannot check 45457193Smuller * this until we are ready to write since there is no spec that says all 45557193Smuller * volumes in a single archive have to be of the same type... 45657193Smuller * Return: 45757193Smuller * 0 if we can append, -1 otherwise. 45857193Smuller */ 45957193Smuller 46057193Smuller #if __STDC__ 46157193Smuller int 46257193Smuller ar_app_ok(void) 46357193Smuller #else 46457193Smuller int 46557193Smuller ar_app_ok() 46657193Smuller #endif 46757193Smuller { 46857193Smuller if (artyp == ISPIPE) { 46957193Smuller warn(1, "Cannot append to an archive obtained from a pipe."); 47057193Smuller return(-1); 47157193Smuller } 47257193Smuller 47357193Smuller if (!invld_rec) 47457193Smuller return(0); 47557193Smuller warn(1,"Cannot append, device record size %d does not support pax spec", 47657193Smuller rdblksz); 47757193Smuller return(-1); 47857193Smuller } 47957193Smuller 48057193Smuller /* 48157193Smuller * ar_read() 48257193Smuller * read up to a specified number of bytes from the archive into the 48357193Smuller * supplied buffer. When dealing with tapes we may not always be able to 48457193Smuller * read what we want. 48557193Smuller * Return: 48657193Smuller * Number of bytes in buffer. 0 for end of file, -1 for a read error. 48757193Smuller */ 48857193Smuller 48957193Smuller #if __STDC__ 49057193Smuller int 49157193Smuller ar_read(register char *buf, register int cnt) 49257193Smuller #else 49357193Smuller int 49457193Smuller ar_read(buf, cnt) 49557193Smuller register char *buf; 49657193Smuller register int cnt; 49757193Smuller #endif 49857193Smuller { 49957193Smuller register int res = 0; 50057193Smuller 50157193Smuller /* 50257193Smuller * if last i/o was in error, no more reads until reset or new volume 50357193Smuller */ 50457193Smuller if (lstrval <= 0) 50557193Smuller return(lstrval); 50657193Smuller 50757193Smuller /* 50857193Smuller * how we read must be based on device type 50957193Smuller */ 51057193Smuller switch (artyp) { 51157193Smuller case ISTAPE: 51257193Smuller if ((res = read(arfd, buf, cnt)) > 0) { 51357193Smuller /* 51457193Smuller * CAUTION: tape systems may not always return the same 51557193Smuller * sized records so we leave blksz == MAXBLK. The 51657193Smuller * physical record size that a tape drive supports is 51757193Smuller * very hard to determine in a uniform and portable 51857193Smuller * manner. 51957193Smuller */ 52057193Smuller io_ok = 1; 52157193Smuller if (res != rdblksz) { 52257193Smuller /* 52357193Smuller * Record size changed. If this is happens on 52457535Smuller * any record after the first, we probably have 52557535Smuller * a tape drive which has a fixed record size 52657535Smuller * we are getting multiple records in a single 52757535Smuller * read). Watch out for record blocking that 52857535Smuller * violates pax spec (must be a multiple of 52957535Smuller * BLKMULT). 53057193Smuller */ 53157193Smuller rdblksz = res; 53257193Smuller if (rdblksz % BLKMULT) 53357193Smuller invld_rec = 1; 53457193Smuller } 53557193Smuller return(res); 53657193Smuller } 53757193Smuller break; 53857193Smuller case ISREG: 53957193Smuller case ISBLK: 54057193Smuller case ISCHR: 54157193Smuller case ISPIPE: 54257193Smuller default: 54357193Smuller /* 54457193Smuller * Files are so easy to deal with. These other things cannot 54557193Smuller * be trusted at all. So when we are dealing with character 54657193Smuller * devices and pipes we just take what they have ready for us 54757193Smuller * and return. Trying to do anything else with them runs the 54857193Smuller * risk of failure. 54957193Smuller */ 55057193Smuller if ((res = read(arfd, buf, cnt)) > 0) { 55157193Smuller io_ok = 1; 55257193Smuller return(res); 55357193Smuller } 55457193Smuller break; 55557193Smuller } 55657193Smuller 55757193Smuller /* 55857193Smuller * We are in trouble at this point, something is broken... 55957193Smuller */ 56057193Smuller lstrval = res; 56157193Smuller if (res < 0) 56257193Smuller syswarn(1, errno, "Failed read on archive volume %d", arvol); 56357193Smuller else 56457193Smuller warn(0, "End of archive volume %d reached", arvol); 56557193Smuller return(res); 56657193Smuller } 56757193Smuller 56857193Smuller /* 56957193Smuller * ar_write() 57057193Smuller * Write a specified number of bytes in supplied buffer to the archive 57157193Smuller * device so it appears as a single "block". Deals with errors and tries 57257193Smuller * to recover when faced with short writes. 57357193Smuller * Return: 57457193Smuller * Number of bytes written. 0 indicates end of volume reached and with no 57557193Smuller * flaws (as best that can be detected). A -1 indicates an unrecoverable 57657193Smuller * error in the archive occured. 57757193Smuller */ 57857193Smuller 57957193Smuller #if __STDC__ 58057193Smuller int 58157193Smuller ar_write(register char *buf, register int bsz) 58257193Smuller #else 58357193Smuller int 58457193Smuller ar_write(buf, bsz) 58557193Smuller register char *buf; 58657193Smuller register int bsz; 58757193Smuller #endif 58857193Smuller { 58957193Smuller register int res; 59057193Smuller off_t cpos; 59157193Smuller 59257193Smuller /* 59357193Smuller * do not allow pax to create a "bad" archive. Once a write fails on 59457193Smuller * an archive volume prevent further writes to it. 59557193Smuller */ 59657193Smuller if (lstrval <= 0) 59757193Smuller return(lstrval); 59857193Smuller 59957193Smuller if ((res = write(arfd, buf, bsz)) == bsz) { 60057578Smuller wr_trail = 1; 60157193Smuller io_ok = 1; 60257193Smuller return(bsz); 60357193Smuller } 60457193Smuller /* 60557193Smuller * write broke, see what we can do with it. We try to send any partial 60657535Smuller * writes that may violate pax spec to the next archive volume. 60757193Smuller */ 60857193Smuller if (res < 0) 60957193Smuller lstrval = res; 61057193Smuller else 61157193Smuller lstrval = 0; 61257193Smuller 61357193Smuller switch (artyp) { 61457193Smuller case ISREG: 61557193Smuller if ((res > 0) && (res % BLKMULT)) { 61657193Smuller /* 61757193Smuller * try to fix up partial writes which are not BLKMULT 61857193Smuller * in size by forcing the runt record to next archive 61957193Smuller * volume 62057193Smuller */ 62157193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 62257193Smuller break; 62357193Smuller cpos -= (off_t)res; 62457193Smuller if (ftruncate(arfd, cpos) < 0) 62557193Smuller break; 62657193Smuller res = lstrval = 0; 62757193Smuller break; 62857193Smuller } 62957193Smuller if (res >= 0) 63057193Smuller break; 63157193Smuller /* 63257193Smuller * if file is out of space, handle it like a return of 0 63357193Smuller */ 63457193Smuller if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT)) 63557193Smuller res = lstrval = 0; 63657193Smuller break; 63757193Smuller case ISTAPE: 63857193Smuller case ISCHR: 63957193Smuller case ISBLK: 64057193Smuller if (res >= 0) 64157193Smuller break; 64257193Smuller if (errno == EACCES) { 64357193Smuller warn(0, "Write failed, archive is write protected."); 64457193Smuller res = lstrval = 0; 64557193Smuller return(0); 64657193Smuller } 64757193Smuller /* 64857193Smuller * see if we reached the end of media, if so force a change to 64957193Smuller * the next volume 65057193Smuller */ 65157193Smuller if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO)) 65257193Smuller res = lstrval = 0; 65357193Smuller break; 65457193Smuller case ISPIPE: 65557193Smuller default: 65657193Smuller /* 65757193Smuller * we cannot fix errors to these devices 65857193Smuller */ 65957193Smuller break; 66057193Smuller } 66157193Smuller 66257193Smuller /* 66357193Smuller * Better tell the user the bad news... 66457535Smuller * if this is a block aligned archive format, we may have a bad archive 66557535Smuller * if the format wants the header to start at a BLKMULT boundry. While 66657193Smuller * we can deal with the mis-aligned data, it violates spec and other 66757193Smuller * archive readers will likely fail. if the format is not block 66857535Smuller * aligned, the user may be lucky (and the archive is ok). 66957193Smuller */ 67057578Smuller if (res >= 0) { 67157578Smuller if (res > 0) 67257578Smuller wr_trail = 1; 67357193Smuller io_ok = 1; 67457578Smuller } 67557578Smuller 67657578Smuller /* 67757578Smuller * If we were trying to rewrite the trailer and it didn't work, we 67857578Smuller * must quit right away. 67957578Smuller */ 68057578Smuller if (!wr_trail && (res <= 0)) { 68157578Smuller warn(1,"Unable to append, trailer re-write failed. Quitting."); 68257578Smuller return(res); 68357578Smuller } 68457578Smuller 68557578Smuller if (res == 0) 68657193Smuller warn(0, "End of archive volume %d reached", arvol); 68757193Smuller else if (res < 0) 68857193Smuller syswarn(1, errno, "Failed write to archive volume: %d", arvol); 68957193Smuller else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0)) 69057193Smuller warn(0,"WARNING: partial archive write. Archive MAY BE FLAWED"); 69157193Smuller else 69257193Smuller warn(1,"WARNING: partial archive write. Archive IS FLAWED"); 69357193Smuller return(res); 69457193Smuller } 69557193Smuller 69657193Smuller /* 69757193Smuller * ar_rdsync() 69857193Smuller * Try to move past a bad spot on a flawed archive as needed to continue 69957193Smuller * I/O. Clears error flags to allow I/O to continue. 70057193Smuller * Return: 70157193Smuller * 0 when ok to try i/o again, -1 otherwise. 70257193Smuller */ 70357193Smuller 70457193Smuller #if __STDC__ 70557193Smuller int 70657193Smuller ar_rdsync(void) 70757193Smuller #else 70857193Smuller int 70957193Smuller ar_rdsync() 71057193Smuller #endif 71157193Smuller { 71257193Smuller long fsbz; 71357193Smuller off_t cpos; 71457193Smuller off_t mpos; 71557193Smuller struct mtop mb; 71657193Smuller 71757193Smuller /* 71857193Smuller * Fail resync attempts at user request (done) or this is going to be 71957193Smuller * an update/append to a existing archive. if last i/o hit media end, 72057193Smuller * we need to go to the next volume not try a resync 72157193Smuller */ 72257193Smuller if ((done > 0) || (lstrval == 0)) 72357193Smuller return(-1); 72457193Smuller 72557193Smuller if ((act == APPND) || (act == ARCHIVE)) { 72657193Smuller warn(1, "Cannot allow updates to an archive with flaws."); 72757193Smuller return(-1); 72857193Smuller } 72957193Smuller if (io_ok) 73057193Smuller did_io = 1; 73157193Smuller 73257193Smuller switch(artyp) { 73357193Smuller case ISTAPE: 73457193Smuller /* 73557193Smuller * if the last i/o was a successful data transfer, we assume 73657193Smuller * the fault is just a bad record on the tape that we are now 73757193Smuller * past. If we did not get any data since the last resync try 73857193Smuller * to move the tape foward one PHYSICAL record past any 73957193Smuller * damaged tape section. Some tape drives are stubborn and need 74057193Smuller * to be pushed. 74157193Smuller */ 74257193Smuller if (io_ok) { 74357193Smuller io_ok = 0; 74457193Smuller lstrval = 1; 74557193Smuller break; 74657193Smuller } 74757193Smuller mb.mt_op = MTFSR; 74857193Smuller mb.mt_count = 1; 74957193Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) 75057193Smuller break; 75157193Smuller lstrval = 1; 75257193Smuller break; 75357193Smuller case ISREG: 75457193Smuller case ISCHR: 75557193Smuller case ISBLK: 75657193Smuller /* 75757193Smuller * try to step over the bad part of the device. 75857193Smuller */ 75957193Smuller io_ok = 0; 76057193Smuller if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) 76157193Smuller fsbz = BLKMULT; 76257193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 76357193Smuller break; 76457193Smuller mpos = fsbz - (cpos % (off_t)fsbz); 76557193Smuller if (lseek(arfd, mpos, SEEK_CUR) < 0) 76657193Smuller break; 76757193Smuller lstrval = 1; 76857193Smuller break; 76957193Smuller case ISPIPE: 77057193Smuller default: 77157193Smuller /* 77257193Smuller * cannot recover on these archive device types 77357193Smuller */ 77457193Smuller io_ok = 0; 77557193Smuller break; 77657193Smuller } 77757193Smuller if (lstrval <= 0) { 77857535Smuller warn(1, "Unable to recover from an archive read failure."); 77957193Smuller return(-1); 78057193Smuller } 78157193Smuller warn(0, "Attempting to recover from an archive read failure."); 78257193Smuller return(0); 78357193Smuller } 78457193Smuller 78557193Smuller /* 78657193Smuller * ar_fow() 78757193Smuller * Move the I/O position within the archive foward the specified number of 78857193Smuller * bytes as supported by the device. If we cannot move the requested 78957193Smuller * number of bytes, return the actual number of bytes moved in skipped. 79057193Smuller * Return: 79157193Smuller * 0 if moved the requested distance, -1 on complete failure, 1 on 79257193Smuller * partial move (the amount moved is in skipped) 79357193Smuller */ 79457193Smuller 79557193Smuller #if __STDC__ 79657193Smuller int 79757193Smuller ar_fow(off_t sksz, off_t *skipped) 79857193Smuller #else 79957193Smuller int 80057193Smuller ar_fow(sksz, skipped) 80157193Smuller off_t sksz; 80257193Smuller off_t *skipped; 80357193Smuller #endif 80457193Smuller { 80557193Smuller off_t cpos; 80657193Smuller off_t mpos; 80757193Smuller 80857193Smuller *skipped = 0; 80957193Smuller if (sksz <= 0) 81057193Smuller return(0); 81157193Smuller 81257193Smuller /* 81357193Smuller * we cannot move foward at EOF or error 81457193Smuller */ 81557193Smuller if (lstrval <= 0) 81657193Smuller return(lstrval); 81757193Smuller 81857193Smuller /* 81957193Smuller * Safer to read forward on devices where it is hard to find the end of 82057193Smuller * the media without reading to it. With tapes we cannot be sure of the 82157193Smuller * number of physical blocks to skip (we do not know physical block 82257193Smuller * size at this point), so we must only read foward on tapes! 82357193Smuller */ 82457193Smuller if (artyp != ISREG) 82557193Smuller return(0); 82657193Smuller 82757193Smuller /* 82857193Smuller * figure out where we are in the archive 82957193Smuller */ 83057193Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) { 83157193Smuller /* 83257193Smuller * we can be asked to move farther than there are bytes in this 83357193Smuller * volume, if so, just go to file end and let normal buf_fill() 83457193Smuller * deal with the end of file (it will go to next volume by 83557193Smuller * itself) 83657193Smuller */ 83757193Smuller if ((mpos = cpos + sksz) > arsb.st_size) { 83857193Smuller *skipped = arsb.st_size - cpos; 83957193Smuller mpos = arsb.st_size; 84057193Smuller } else 84157193Smuller *skipped = sksz; 84257193Smuller if (lseek(arfd, mpos, SEEK_SET) >= 0) 84357193Smuller return(0); 84457193Smuller } 84557193Smuller syswarn(1, errno, "Foward positioning operation on archive failed"); 84657193Smuller lstrval = -1; 84757193Smuller return(-1); 84857193Smuller } 84957193Smuller 85057193Smuller /* 85157193Smuller * ar_rev() 85257193Smuller * move the i/o position within the archive backwards the specified byte 85357193Smuller * count as supported by the device. With tapes drives we RESET rdblksz to 85457193Smuller * the PHYSICAL blocksize. 85557193Smuller * NOTE: We should only be called to move backwards so we can rewrite the 85657193Smuller * last records (the trailer) of an archive (APPEND). 85757193Smuller * Return: 85857193Smuller * 0 if moved the requested distance, -1 on complete failure 85957193Smuller */ 86057193Smuller 86157193Smuller #if __STDC__ 86257193Smuller int 86357193Smuller ar_rev(off_t sksz) 86457193Smuller #else 86557193Smuller int 86657193Smuller ar_rev(sksz) 86757193Smuller off_t sksz; 86857193Smuller #endif 86957193Smuller { 87057193Smuller off_t cpos; 87157193Smuller struct mtop mb; 87257794Smuller register int phyblk; 87357193Smuller 87457193Smuller /* 87557578Smuller * make sure we do not have try to reverse on a flawed archive 87657193Smuller */ 87757193Smuller if (lstrval < 0) 87857193Smuller return(lstrval); 87957193Smuller 88057193Smuller switch(artyp) { 88157193Smuller case ISPIPE: 88257578Smuller if (sksz <= 0) 88357578Smuller break; 88457193Smuller /* 88557193Smuller * cannot go backwards on these critters 88657193Smuller */ 88757578Smuller warn(1, "Reverse positioning on pipes is not supported."); 88857578Smuller lstrval = -1; 88957578Smuller return(-1); 89057193Smuller case ISREG: 89157193Smuller case ISBLK: 89257193Smuller case ISCHR: 89357193Smuller default: 89457578Smuller if (sksz <= 0) 89557578Smuller break; 89657578Smuller 89757193Smuller /* 89857193Smuller * For things other than files, backwards movement has a very 89957193Smuller * high probability of failure as we really do not know the 90057193Smuller * true attributes of the device we are talking to (the device 90157193Smuller * may not even have the ability to lseek() in any direction). 90257578Smuller * First we figure out where we are in the archive. 90357193Smuller */ 90457578Smuller if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) { 90557578Smuller syswarn(1, errno, 90657578Smuller "Unable to obtain current archive byte offset"); 90757578Smuller lstrval = -1; 90857578Smuller return(-1); 90957578Smuller } 91057193Smuller 91157193Smuller /* 91257193Smuller * we may try to go backwards past the start when the archive 91357193Smuller * is only a single record. If this hapens and we are on a 91457193Smuller * multi volume archive, we need to go to the end of the 91557193Smuller * previous volume and continue our movement backwards from 91657578Smuller * there. 91757193Smuller */ 91857193Smuller if ((cpos -= sksz) < (off_t)0L) { 91957193Smuller if (arvol > 1) { 92057578Smuller /* 92157578Smuller * this should never happen 92257578Smuller */ 92357578Smuller warn(1,"Reverse position on previous volume."); 92457193Smuller lstrval = -1; 92557193Smuller return(-1); 92657193Smuller } 92757193Smuller cpos = (off_t)0L; 92857193Smuller } 92957578Smuller if (lseek(arfd, cpos, SEEK_SET) < 0) { 93057578Smuller syswarn(1, errno, "Unable to seek archive backwards"); 93157578Smuller lstrval = -1; 93257578Smuller return(-1); 93357578Smuller } 93457578Smuller break; 93557193Smuller case ISTAPE: 93657193Smuller /* 93757193Smuller * Calculate and move the proper number of PHYSICAL tape 93857578Smuller * blocks. If the sksz is not an even multiple of the physical 93957193Smuller * tape size, we cannot do the move (this should never happen). 94057193Smuller * (We also cannot handler trailers spread over two vols). 94157578Smuller * get_phys() also makes sure we are in front of the filemark. 94257193Smuller */ 94357794Smuller if ((phyblk = get_phys()) <= 0) { 94457578Smuller lstrval = -1; 94557578Smuller return(-1); 94657193Smuller } 94757193Smuller 94857578Smuller /* 94957578Smuller * make sure future tape reads only go by physical tape block 95057578Smuller * size (set rdblksz to the real size). 95157578Smuller */ 95257578Smuller rdblksz = phyblk; 95357578Smuller 95457578Smuller /* 95557578Smuller * if no movement is required, just return (we must be after 95657578Smuller * get_phys() so the physical blocksize is properly set) 95757578Smuller */ 95857578Smuller if (sksz <= 0) 95957578Smuller break; 96057578Smuller 96157578Smuller /* 96257578Smuller * ok we have to move. Make sure the tape drive can do it. 96357578Smuller */ 96457193Smuller if (sksz % phyblk) { 96557578Smuller warn(1, 96657578Smuller "Tape drive unable to backspace requested amount"); 96757193Smuller lstrval = -1; 96857193Smuller return(-1); 96957193Smuller } 97057193Smuller 97157578Smuller /* 97257578Smuller * move backwards the requested number of bytes 97357578Smuller */ 97457193Smuller mb.mt_op = MTBSR; 97557193Smuller mb.mt_count = sksz/phyblk; 97657578Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 97757578Smuller syswarn(1,errno, "Unable to backspace tape %d blocks.", 97857578Smuller mb.mt_count); 97957578Smuller lstrval = -1; 98057578Smuller return(-1); 98157578Smuller } 98257578Smuller break; 98357193Smuller } 98457578Smuller lstrval = 1; 98557578Smuller return(0); 98657193Smuller } 98757193Smuller 98857193Smuller /* 98957193Smuller * get_phys() 99057578Smuller * Determine the physical block size on a tape drive. We need the physical 99157578Smuller * block size so we know how many bytes we skip over when we move with 99257578Smuller * mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when 99357578Smuller * return. 99457578Smuller * This is one really SLOW routine... 99557193Smuller * Return: 99657794Smuller * physical block size if ok (ok > 0), -1 otherwise 99757193Smuller */ 99857193Smuller 99957193Smuller #if __STDC__ 100057193Smuller static int 100157193Smuller get_phys(void) 100257193Smuller #else 100357193Smuller static int 100457193Smuller get_phys() 100557193Smuller #endif 100657193Smuller { 100757578Smuller register int padsz = 0; 100857535Smuller register int res; 100957794Smuller register int phyblk; 101057535Smuller struct mtop mb; 101157578Smuller char scbuf[MAXBLK]; 101257193Smuller 101357193Smuller /* 101457578Smuller * move to the file mark, and then back up one record and read it. 101557578Smuller * this should tell us the physical record size the tape is using. 101657578Smuller */ 101757578Smuller if (lstrval == 1) { 101857578Smuller /* 101957578Smuller * we know we are at file mark when we get back a 0 from 102057578Smuller * read() 102157578Smuller */ 102257578Smuller while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) 102357578Smuller padsz += res; 102457578Smuller if (res < 0) { 102557578Smuller syswarn(1, errno, "Unable to locate tape filemark."); 102657578Smuller return(-1); 102757578Smuller } 102857578Smuller } 102957193Smuller 103057578Smuller /* 103157578Smuller * move backwards over the file mark so we are at the end of the 103257578Smuller * last record. 103357578Smuller */ 103457578Smuller mb.mt_op = MTBSF; 103557193Smuller mb.mt_count = 1; 103657578Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 103757578Smuller syswarn(1, errno, "Unable to backspace over tape filemark."); 103857193Smuller return(-1); 103957535Smuller } 104057193Smuller 104157193Smuller /* 104257578Smuller * move backwards so we are in front of the last record and read it to 104357578Smuller * get physical tape blocksize. 104457193Smuller */ 104557578Smuller mb.mt_op = MTBSR; 104657578Smuller mb.mt_count = 1; 104757578Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 104857578Smuller syswarn(1, errno, "Unable to backspace over last tape block."); 104957193Smuller return(-1); 105057578Smuller } 105157578Smuller if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) { 105257578Smuller syswarn(1, errno, "Cannot determine archive tape blocksize."); 105357578Smuller return(-1); 105457578Smuller } 105557535Smuller 105657535Smuller /* 105757578Smuller * read foward to the file mark, then back up in front of the filemark 105857578Smuller * (this is a bit paranoid, but should be safe to do). 105957535Smuller */ 106057578Smuller while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) 106157578Smuller ; 106257578Smuller if (res < 0) { 106357578Smuller syswarn(1, errno, "Unable to locate tape filemark."); 106457535Smuller return(-1); 106557578Smuller } 106657578Smuller mb.mt_op = MTBSF; 106757578Smuller mb.mt_count = 1; 106857578Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 106957578Smuller syswarn(1, errno, "Unable to backspace over tape filemark."); 107057578Smuller return(-1); 107157578Smuller } 107257535Smuller 107357535Smuller /* 107457578Smuller * set lstrval so we know that the filemark has not been seen 107557535Smuller */ 107657578Smuller lstrval = 1; 107757578Smuller 107857578Smuller /* 107957578Smuller * return if there was no padding 108057578Smuller */ 108157578Smuller if (padsz == 0) 108257794Smuller return(phyblk); 108357535Smuller 108457535Smuller /* 108557578Smuller * make sure we can move backwards over the padding. (this should 108657578Smuller * never fail). 108757535Smuller */ 108857578Smuller if (padsz % phyblk) { 108957578Smuller warn(1, "Tape drive unable to backspace requested amount"); 109057535Smuller return(-1); 109157578Smuller } 109257535Smuller 109357535Smuller /* 109457578Smuller * move backwards over the padding so the head is where it was when 109557578Smuller * we were first called (if required). 109657535Smuller */ 109757578Smuller mb.mt_op = MTBSR; 109857578Smuller mb.mt_count = padsz/phyblk; 109957578Smuller if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 110057578Smuller syswarn(1,errno,"Unable to backspace tape over %d pad blocks", 110157578Smuller mb.mt_count); 110257535Smuller return(-1); 110357578Smuller } 110457794Smuller return(phyblk); 110557193Smuller } 110657193Smuller 110757193Smuller /* 110857193Smuller * ar_next() 110957535Smuller * prompts the user for the next volume in this archive. For some devices 111057535Smuller * we may allow the media to be changed. Otherwise a new archive is 111157535Smuller * prompted for. By pax spec, if there is no controlling tty or an eof is 111257535Smuller * read on tty input, we must quit pax. 111357193Smuller * Return: 111457193Smuller * 0 when ready to continue, -1 when all done 111557193Smuller */ 111657193Smuller 111757193Smuller #if __STDC__ 111857193Smuller int 111957193Smuller ar_next(void) 112057193Smuller #else 112157193Smuller int 112257193Smuller ar_next() 112357193Smuller #endif 112457193Smuller { 112557193Smuller char buf[PAXPATHLEN+2]; 112657193Smuller static int freeit = 0; 112757193Smuller sigset_t o_mask; 112857193Smuller 112957193Smuller /* 113057535Smuller * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so 113157193Smuller * things like writing EOF etc will be done) (Watch out ar_close() can 113257535Smuller * also be called via a signal handler, so we must prevent a race. 113357193Smuller */ 113457193Smuller if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0) 113557535Smuller syswarn(0, errno, "Unable to set signal mask"); 113657193Smuller ar_close(); 113757193Smuller if (sigprocmask(SIG_SETMASK, &o_mask, (sigset_t *)NULL) < 0) 113857535Smuller syswarn(0, errno, "Unable to restore signal mask"); 113957193Smuller 114057578Smuller if (done || !wr_trail) 114157193Smuller return(-1); 114257193Smuller 114357193Smuller tty_prnt("\nATTENTION! Pax archive volume change required.\n"); 114457193Smuller 114557193Smuller /* 114657193Smuller * if i/o is on stdin or stdout, we cannot reopen it (we do not know 114757535Smuller * the name), the user will be forced to type it in. 114857193Smuller */ 114957193Smuller if (strcmp(arcname, STDO) && strcmp(arcname, STDN) && (artyp != ISREG) 115057193Smuller && (artyp != ISPIPE)) { 115157193Smuller if (artyp == ISTAPE) { 115257193Smuller tty_prnt("%s ready for archive tape volume: %d\n", 115357193Smuller arcname, arvol); 115457193Smuller tty_prnt("Load the NEXT TAPE on the tape drive"); 115557193Smuller } else { 115657193Smuller tty_prnt("%s ready for archive volume: %d\n", 115757193Smuller arcname, arvol); 115857193Smuller tty_prnt("Load the NEXT STORAGE MEDIA (if required)"); 115957193Smuller } 116057193Smuller 116157193Smuller if ((act == ARCHIVE) || (act == APPND)) 116257193Smuller tty_prnt(" and make sure it is WRITE ENABLED.\n"); 116357193Smuller else 116457193Smuller tty_prnt("\n"); 116557193Smuller 116657193Smuller for(;;) { 116757193Smuller tty_prnt("Type \"y\" to continue, \".\" to quit pax,"); 116857193Smuller tty_prnt(" or \"s\" to switch to new device.\nIf you"); 116957193Smuller tty_prnt(" cannot change storage media, type \"s\"\n"); 117057193Smuller tty_prnt("Is the device ready and online? > "); 117157193Smuller 117257193Smuller if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){ 117357193Smuller done = 1; 117457193Smuller lstrval = -1; 117557193Smuller tty_prnt("Quitting pax!\n"); 117657193Smuller vfpart = 0; 117757193Smuller return(-1); 117857193Smuller } 117957193Smuller 118057193Smuller if ((buf[0] == '\0') || (buf[1] != '\0')) { 118157193Smuller tty_prnt("%s unknown command, try again\n",buf); 118257193Smuller continue; 118357193Smuller } 118457193Smuller 118557193Smuller switch (buf[0]) { 118657193Smuller case 'y': 118757193Smuller case 'Y': 118857193Smuller /* 118957193Smuller * we are to continue with the same device 119057193Smuller */ 119157193Smuller if (ar_open(arcname) >= 0) 119257193Smuller return(0); 119357193Smuller tty_prnt("Cannot re-open %s, try again\n", 119457193Smuller arcname); 119557193Smuller continue; 119657193Smuller case 's': 119757193Smuller case 'S': 119857193Smuller /* 119957193Smuller * user wants to open a different device 120057193Smuller */ 120157193Smuller tty_prnt("Switching to a different archive\n"); 120257193Smuller break; 120357193Smuller default: 120457193Smuller tty_prnt("%s unknown command, try again\n",buf); 120557193Smuller continue; 120657193Smuller } 120757193Smuller break; 120857193Smuller } 120957193Smuller } else 121057193Smuller tty_prnt("Ready for archive volume: %d\n", arvol); 121157193Smuller 121257193Smuller /* 121357193Smuller * have to go to a different archive 121457193Smuller */ 121557193Smuller for (;;) { 121657193Smuller tty_prnt("Input archive name or \".\" to quit pax.\n"); 121757193Smuller tty_prnt("Archive name > "); 121857193Smuller 121957193Smuller if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) { 122057193Smuller done = 1; 122157193Smuller lstrval = -1; 122257193Smuller tty_prnt("Quitting pax!\n"); 122357193Smuller vfpart = 0; 122457193Smuller return(-1); 122557193Smuller } 122657193Smuller if (buf[0] == '\0') { 122757193Smuller tty_prnt("Empty file name, try again\n"); 122857193Smuller continue; 122957193Smuller } 123057193Smuller if (!strcmp(buf, "..")) { 123157193Smuller tty_prnt("Illegal file name: .. try again\n"); 123257193Smuller continue; 123357193Smuller } 123457193Smuller if (strlen(buf) > PAXPATHLEN) { 123557193Smuller tty_prnt("File name too long, try again\n"); 123657193Smuller continue; 123757193Smuller } 123857193Smuller 123957193Smuller /* 124057193Smuller * try to open new archive 124157193Smuller */ 124257193Smuller if (ar_open(buf) >= 0) { 124357193Smuller if (freeit) { 124457193Smuller (void)free(arcname); 124557193Smuller freeit = 0; 124657193Smuller } 124757193Smuller if ((arcname = strdup(buf)) == NULL) { 124857193Smuller done = 1; 124957193Smuller lstrval = -1; 125057535Smuller warn(0, "Cannot save archive name."); 125157193Smuller return(-1); 125257193Smuller } 125357193Smuller freeit = 1; 125457193Smuller break; 125557193Smuller } 125657193Smuller tty_prnt("Cannot open %s, try again\n", buf); 125757193Smuller continue; 125857193Smuller } 125957193Smuller return(0); 126057193Smuller } 1261