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