ar_io.c revision 114583
155714Skris/*- 255714Skris * Copyright (c) 1992 Keith Muller. 355714Skris * Copyright (c) 1992, 1993 455714Skris * The Regents of the University of California. All rights reserved. 555714Skris * 655714Skris * This code is derived from software contributed to Berkeley by 755714Skris * Keith Muller of the University of California, San Diego. 855714Skris * 955714Skris * Redistribution and use in source and binary forms, with or without 1055714Skris * modification, are permitted provided that the following conditions 1155714Skris * are met: 1255714Skris * 1. Redistributions of source code must retain the above copyright 1355714Skris * notice, this list of conditions and the following disclaimer. 1455714Skris * 2. Redistributions in binary form must reproduce the above copyright 1555714Skris * notice, this list of conditions and the following disclaimer in the 1655714Skris * documentation and/or other materials provided with the distribution. 1755714Skris * 3. All advertising materials mentioning features or use of this software 1855714Skris * must display the following acknowledgement: 1955714Skris * This product includes software developed by the University of 2055714Skris * California, Berkeley and its contributors. 2155714Skris * 4. Neither the name of the University nor the names of its contributors 2255714Skris * may be used to endorse or promote products derived from this software 2355714Skris * without specific prior written permission. 2455714Skris * 2555714Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2655714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2755714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2855714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2955714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3055714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3155714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3255714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3355714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3455714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3555714Skris * SUCH DAMAGE. 3655714Skris */ 3755714Skris 3855714Skris#ifndef lint 3955714Skris#if 0 4055714Skrisstatic char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94"; 4155714Skris#endif 4255714Skris#endif /* not lint */ 4355714Skris#include <sys/cdefs.h> 4455714Skris__FBSDID("$FreeBSD: head/bin/pax/ar_io.c 114583 2003-05-03 16:39:34Z markm $"); 4555714Skris 4655714Skris#include <sys/types.h> 4755714Skris#include <sys/ioctl.h> 4855714Skris#include <sys/mtio.h> 4955714Skris#include <sys/stat.h> 5055714Skris#include <sys/wait.h> 5155714Skris#include <err.h> 5255714Skris#include <errno.h> 5355714Skris#include <fcntl.h> 5455714Skris#include <signal.h> 5555714Skris#include <stdint.h> 5655714Skris#include <stdio.h> 5755714Skris#include <string.h> 5855714Skris#include <stdlib.h> 5955714Skris#include <unistd.h> 6055714Skris#include "pax.h" 61194206Ssimon#include "options.h" 62194206Ssimon#include "extern.h" 63194206Ssimon 6455714Skris/* 6555714Skris * Routines which deal directly with the archive I/O device/file. 66167612Ssimon */ 6755714Skris 68194206Ssimon#define DMOD 0666 /* default mode of created archives */ 69194206Ssimon#define EXT_MODE O_RDONLY /* open mode for list/extract */ 70194206Ssimon#define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC) /* mode for archive */ 71194206Ssimon#define APP_MODE O_RDWR /* mode for append */ 72194206Ssimon 73194206Ssimonstatic char none[] = "<NONE>"; /* pseudo name for no file */ 74160814Ssimonstatic char stdo[] = "<STDOUT>"; /* pseudo name for stdout */ 7555714Skrisstatic char stdn[] = "<STDIN>"; /* pseudo name for stdin */ 7655714Skrisstatic int arfd = -1; /* archive file descriptor */ 7755714Skrisstatic int artyp = ISREG; /* archive type: file/FIFO/tape */ 7855714Skrisstatic int arvol = 1; /* archive volume number */ 7955714Skrisstatic int lstrval = -1; /* return value from last i/o */ 8055714Skrisstatic int io_ok; /* i/o worked on volume after resync */ 8155714Skrisstatic int did_io; /* did i/o ever occur on volume? */ 8255714Skrisstatic int done; /* set via tty termination */ 8355714Skrisstatic struct stat arsb; /* stat of archive device at open */ 8455714Skrisstatic int invld_rec; /* tape has out of spec record size */ 8555714Skrisstatic int wr_trail = 1; /* trailer was rewritten in append */ 8655714Skrisstatic int can_unlnk = 0; /* do we unlink null archives? */ 8755714Skrisconst char *arcname; /* printable name of archive */ 88160814Ssimonconst char *gzip_program; /* name of gzip program */ 8955714Skrisstatic pid_t zpid = -1; /* pid of child process */ 9055714Skris 9155714Skrisstatic int get_phys(void); 9255714Skrisextern sigset_t s_mask; 9355714Skrisstatic void ar_start_gzip(int, const char *, int); 9455714Skris 95160814Ssimon/* 96160814Ssimon * ar_open() 97160814Ssimon * Opens the next archive volume. Determines the type of the device and 98160814Ssimon * sets up block sizes as required by the archive device and the format. 9955714Skris * Note: we may be called with name == NULL on the first open only. 10055714Skris * Return: 10155714Skris * -1 on failure, 0 otherwise 10255714Skris */ 10355714Skris 10455714Skrisint 10555714Skrisar_open(const char *name) 10655714Skris{ 10755714Skris struct mtget mb; 10855714Skris 10955714Skris if (arfd != -1) 11055714Skris (void)close(arfd); 11155714Skris arfd = -1; 11255714Skris can_unlnk = did_io = io_ok = invld_rec = 0; 11355714Skris artyp = ISREG; 11455714Skris flcnt = 0; 11555714Skris 11655714Skris /* 11755714Skris * open based on overall operation mode 11855714Skris */ 11955714Skris switch (act) { 12055714Skris case LIST: 12155714Skris case EXTRACT: 12255714Skris if (name == NULL) { 12359191Skris arfd = STDIN_FILENO; 12459191Skris arcname = stdn; 12559191Skris } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0) 12659191Skris syswarn(0, errno, "Failed open to read on %s", name); 12759191Skris if (arfd != -1 && gzip_program != NULL) 12855714Skris ar_start_gzip(arfd, gzip_program, 0); 129194206Ssimon break; 130194206Ssimon case ARCHIVE: 131194206Ssimon if (name == NULL) { 132194206Ssimon arfd = STDOUT_FILENO; 133194206Ssimon arcname = stdo; 134194206Ssimon } else if ((arfd = open(name, AR_MODE, DMOD)) < 0) 135194206Ssimon syswarn(0, errno, "Failed open to write on %s", name); 136194206Ssimon else 137194206Ssimon can_unlnk = 1; 138194206Ssimon if (arfd != -1 && gzip_program != NULL) 139194206Ssimon ar_start_gzip(arfd, gzip_program, 1); 140194206Ssimon break; 141194206Ssimon case APPND: 142194206Ssimon if (name == NULL) { 143194206Ssimon arfd = STDOUT_FILENO; 144194206Ssimon arcname = stdo; 145194206Ssimon } else if ((arfd = open(name, APP_MODE, DMOD)) < 0) 146194206Ssimon syswarn(0, errno, "Failed open to read/write on %s", 147194206Ssimon name); 148194206Ssimon break; 149194206Ssimon case COPY: 150194206Ssimon /* 151194206Ssimon * arfd not used in COPY mode 152194206Ssimon */ 153194206Ssimon arcname = none; 154194206Ssimon lstrval = 1; 155194206Ssimon return(0); 156194206Ssimon } 157194206Ssimon if (arfd < 0) 158194206Ssimon return(-1); 159194206Ssimon 160194206Ssimon if (chdname != NULL) 161194206Ssimon if (chdir(chdname) != 0) 162194206Ssimon syswarn(1, errno, "Failed chdir to %s", chdname); 163194206Ssimon /* 164194206Ssimon * set up is based on device type 165194206Ssimon */ 166194206Ssimon if (fstat(arfd, &arsb) < 0) { 167194206Ssimon syswarn(0, errno, "Failed stat on %s", arcname); 168194206Ssimon (void)close(arfd); 169194206Ssimon arfd = -1; 170194206Ssimon can_unlnk = 0; 171194206Ssimon return(-1); 172194206Ssimon } 173194206Ssimon if (S_ISDIR(arsb.st_mode)) { 174194206Ssimon paxwarn(0, "Cannot write an archive on top of a directory %s", 175194206Ssimon arcname); 176194206Ssimon (void)close(arfd); 177194206Ssimon arfd = -1; 178194206Ssimon can_unlnk = 0; 179194206Ssimon return(-1); 180194206Ssimon } 181194206Ssimon 182194206Ssimon if (S_ISCHR(arsb.st_mode)) 183194206Ssimon artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE; 184194206Ssimon else if (S_ISBLK(arsb.st_mode)) 185194206Ssimon artyp = ISBLK; 186194206Ssimon else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE)) 187194206Ssimon artyp = ISPIPE; 188194206Ssimon else 189194206Ssimon artyp = ISREG; 190194206Ssimon 191194206Ssimon /* 192194206Ssimon * make sure we beyond any doubt that we only can unlink regular files 193194206Ssimon * we created 194194206Ssimon */ 195194206Ssimon if (artyp != ISREG) 196194206Ssimon can_unlnk = 0; 197194206Ssimon /* 198194206Ssimon * if we are writing, we are done 199194206Ssimon */ 200194206Ssimon if (act == ARCHIVE) { 201194206Ssimon blksz = rdblksz = wrblksz; 202194206Ssimon lstrval = 1; 203194206Ssimon return(0); 204194206Ssimon } 205194206Ssimon 206194206Ssimon /* 207194206Ssimon * set default blksz on read. APPNDs writes rdblksz on the last volume 208194206Ssimon * On all new archive volumes, we shift to wrblksz (if the user 209194206Ssimon * specified one, otherwize we will continue to use rdblksz). We 210194206Ssimon * must to set blocksize based on what kind of device the archive is 211194206Ssimon * stored. 212194206Ssimon */ 213194206Ssimon switch(artyp) { 214194206Ssimon case ISTAPE: 215194206Ssimon /* 216194206Ssimon * Tape drives come in at least two flavors. Those that support 217194206Ssimon * variable sized records and those that have fixed sized 218194206Ssimon * records. They must be treated differently. For tape drives 219194206Ssimon * that support variable sized records, we must make large 220194206Ssimon * reads to make sure we get the entire record, otherwise we 221194206Ssimon * will just get the first part of the record (up to size we 222194206Ssimon * asked). Tapes with fixed sized records may or may not return 223194206Ssimon * multiple records in a single read. We really do not care 224194206Ssimon * what the physical record size is UNLESS we are going to 225194206Ssimon * append. (We will need the physical block size to rewrite 226194206Ssimon * the trailer). Only when we are appending do we go to the 227194206Ssimon * effort to figure out the true PHYSICAL record size. 228194206Ssimon */ 229194206Ssimon blksz = rdblksz = MAXBLK; 230194206Ssimon break; 231194206Ssimon case ISPIPE: 232194206Ssimon case ISBLK: 233194206Ssimon case ISCHR: 234194206Ssimon /* 235194206Ssimon * Blocksize is not a major issue with these devices (but must 236194206Ssimon * be kept a multiple of 512). If the user specified a write 237194206Ssimon * block size, we use that to read. Under append, we must 238194206Ssimon * always keep blksz == rdblksz. Otherwise we go ahead and use 239194206Ssimon * the device optimal blocksize as (and if) returned by stat 240194206Ssimon * and if it is within pax specs. 241194206Ssimon */ 242194206Ssimon if ((act == APPND) && wrblksz) { 243194206Ssimon blksz = rdblksz = wrblksz; 244194206Ssimon break; 245194206Ssimon } 246194206Ssimon 247194206Ssimon if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) && 248194206Ssimon ((arsb.st_blksize % BLKMULT) == 0)) 249194206Ssimon rdblksz = arsb.st_blksize; 250194206Ssimon else 251194206Ssimon rdblksz = DEVBLK; 252194206Ssimon /* 253194206Ssimon * For performance go for large reads when we can without harm 254194206Ssimon */ 255194206Ssimon if ((act == APPND) || (artyp == ISCHR)) 256194206Ssimon blksz = rdblksz; 257194206Ssimon else 258194206Ssimon blksz = MAXBLK; 259194206Ssimon break; 260194206Ssimon case ISREG: 261194206Ssimon /* 262194206Ssimon * if the user specified wrblksz works, use it. Under appends 263194206Ssimon * we must always keep blksz == rdblksz 264194206Ssimon */ 265194206Ssimon if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){ 266194206Ssimon blksz = rdblksz = wrblksz; 267194206Ssimon break; 268194206Ssimon } 269194206Ssimon /* 270194206Ssimon * See if we can find the blocking factor from the file size 271194206Ssimon */ 272194206Ssimon for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT) 273194206Ssimon if ((arsb.st_size % rdblksz) == 0) 274194206Ssimon break; 275194206Ssimon /* 276194206Ssimon * When we cannot find a match, we may have a flawed archive. 277194206Ssimon */ 278194206Ssimon if (rdblksz <= 0) 279194206Ssimon rdblksz = FILEBLK; 280194206Ssimon /* 281194206Ssimon * for performance go for large reads when we can 282194206Ssimon */ 283194206Ssimon if (act == APPND) 284194206Ssimon blksz = rdblksz; 285194206Ssimon else 286194206Ssimon blksz = MAXBLK; 287194206Ssimon break; 288194206Ssimon default: 289194206Ssimon /* 290194206Ssimon * should never happen, worse case, slow... 291194206Ssimon */ 292194206Ssimon blksz = rdblksz = BLKMULT; 293194206Ssimon break; 294194206Ssimon } 295194206Ssimon lstrval = 1; 296194206Ssimon return(0); 297194206Ssimon} 298194206Ssimon 299194206Ssimon/* 300194206Ssimon * ar_close() 301194206Ssimon * closes archive device, increments volume number, and prints i/o summary 302194206Ssimon */ 303194206Ssimonvoid 304194206Ssimonar_close(void) 305194206Ssimon{ 306194206Ssimon 307194206Ssimon if (arfd < 0) { 308194206Ssimon did_io = io_ok = flcnt = 0; 309194206Ssimon return; 310194206Ssimon } 311194206Ssimon 312194206Ssimon /* 313194206Ssimon * Close archive file. This may take a LONG while on tapes (we may be 314194206Ssimon * forced to wait for the rewind to complete) so tell the user what is 315194206Ssimon * going on (this avoids the user hitting control-c thinking pax is 316194206Ssimon * broken). 317194206Ssimon */ 318194206Ssimon if (vflag && (artyp == ISTAPE)) { 319194206Ssimon if (vfpart) 320194206Ssimon (void)putc('\n', listf); 321194206Ssimon (void)fprintf(listf, 322194206Ssimon "%s: Waiting for tape drive close to complete...", 323194206Ssimon argv0); 324194206Ssimon (void)fflush(listf); 325194206Ssimon } 326194206Ssimon 327194206Ssimon /* 328194206Ssimon * if nothing was written to the archive (and we created it), we remove 329194206Ssimon * it 330194206Ssimon */ 331194206Ssimon if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) && 332194206Ssimon (arsb.st_size == 0)) { 333194206Ssimon (void)unlink(arcname); 334194206Ssimon can_unlnk = 0; 335194206Ssimon } 336194206Ssimon 337194206Ssimon /* 338194206Ssimon * for a quick extract/list, pax frequently exits before the child 339194206Ssimon * process is done 340194206Ssimon */ 341194206Ssimon if ((act == LIST || act == EXTRACT) && nflag && zpid > 0) { 342194206Ssimon int status; 343194206Ssimon kill(zpid, SIGINT); 344194206Ssimon waitpid(zpid, &status, 0); 345194206Ssimon } 346194206Ssimon 347194206Ssimon (void)close(arfd); 348194206Ssimon 349194206Ssimon if (vflag && (artyp == ISTAPE)) { 350194206Ssimon (void)fputs("done.\n", listf); 351194206Ssimon vfpart = 0; 352194206Ssimon (void)fflush(listf); 353194206Ssimon } 354194206Ssimon arfd = -1; 355194206Ssimon 356194206Ssimon if (!io_ok && !did_io) { 357194206Ssimon flcnt = 0; 358194206Ssimon return; 359194206Ssimon } 360194206Ssimon did_io = io_ok = 0; 361194206Ssimon 362194206Ssimon /* 363194206Ssimon * The volume number is only increased when the last device has data 364194206Ssimon * and we have already determined the archive format. 365194206Ssimon */ 366194206Ssimon if (frmt != NULL) 367194206Ssimon ++arvol; 368194206Ssimon 369194206Ssimon if (!vflag) { 370194206Ssimon flcnt = 0; 371194206Ssimon return; 372194206Ssimon } 373194206Ssimon 374194206Ssimon /* 375194206Ssimon * Print out a summary of I/O for this archive volume. 376194206Ssimon */ 377194206Ssimon if (vfpart) { 378194206Ssimon (void)putc('\n', listf); 379194206Ssimon vfpart = 0; 380194206Ssimon } 381194206Ssimon 382194206Ssimon /* 383194206Ssimon * If we have not determined the format yet, we just say how many bytes 384194206Ssimon * we have skipped over looking for a header to id. there is no way we 385194206Ssimon * could have written anything yet. 386194206Ssimon */ 387194206Ssimon if (frmt == NULL) { 388194206Ssimon# ifdef NET2_STAT 389194206Ssimon (void)fprintf(listf, "%s: unknown format, %lu bytes skipped.\n", 390194206Ssimon argv0, rdcnt); 391194206Ssimon# else 392194206Ssimon (void)fprintf(listf, "%s: unknown format, %ju bytes skipped.\n", 393194206Ssimon argv0, (uintmax_t)rdcnt); 394194206Ssimon# endif 395194206Ssimon (void)fflush(listf); 396194206Ssimon flcnt = 0; 397194206Ssimon return; 398194206Ssimon } 399194206Ssimon 400194206Ssimon if (strcmp(NM_CPIO, argv0) == 0) 401194206Ssimon (void)fprintf(listf, "%llu blocks\n", 402194206Ssimon (unsigned long long)((rdcnt ? rdcnt : wrcnt) / 5120)); 403194206Ssimon else if (strcmp(NM_TAR, argv0) != 0) 404194206Ssimon (void)fprintf(listf, 405194206Ssimon# ifdef NET2_STAT 406194206Ssimon "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n", 407194206Ssimon argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt); 408194206Ssimon# else 409194206Ssimon "%s: %s vol %d, %ju files, %ju bytes read, %ju bytes written.\n", 410194206Ssimon argv0, frmt->name, arvol-1, (uintmax_t)flcnt, 411194206Ssimon (uintmax_t)rdcnt, (uintmax_t)wrcnt); 412194206Ssimon# endif 413194206Ssimon (void)fflush(listf); 414194206Ssimon flcnt = 0; 415194206Ssimon} 416194206Ssimon 417194206Ssimon/* 418194206Ssimon * ar_drain() 419194206Ssimon * drain any archive format independent padding from an archive read 420194206Ssimon * from a socket or a pipe. This is to prevent the process on the 421194206Ssimon * other side of the pipe from getting a SIGPIPE (pax will stop 422194206Ssimon * reading an archive once a format dependent trailer is detected). 423194206Ssimon */ 424194206Ssimonvoid 425194206Ssimonar_drain(void) 426194206Ssimon{ 427194206Ssimon int res; 428194206Ssimon char drbuf[MAXBLK]; 429194206Ssimon 430194206Ssimon /* 431194206Ssimon * we only drain from a pipe/socket. Other devices can be closed 432194206Ssimon * without reading up to end of file. We sure hope that pipe is closed 433194206Ssimon * on the other side so we will get an EOF. 434194206Ssimon */ 435194206Ssimon if ((artyp != ISPIPE) || (lstrval <= 0)) 436194206Ssimon return; 437194206Ssimon 438194206Ssimon /* 439194206Ssimon * keep reading until pipe is drained 440194206Ssimon */ 441194206Ssimon while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0) 442194206Ssimon ; 443194206Ssimon lstrval = res; 444194206Ssimon} 445194206Ssimon 446194206Ssimon/* 447194206Ssimon * ar_set_wr() 448194206Ssimon * Set up device right before switching from read to write in an append. 449194206Ssimon * device dependent code (if required) to do this should be added here. 450194206Ssimon * For all archive devices we are already positioned at the place we want 451194206Ssimon * to start writing when this routine is called. 452194206Ssimon * Return: 453194206Ssimon * 0 if all ready to write, -1 otherwise 454194206Ssimon */ 455194206Ssimon 456194206Ssimonint 457194206Ssimonar_set_wr(void) 458194206Ssimon{ 459194206Ssimon off_t cpos; 460194206Ssimon 461194206Ssimon /* 462194206Ssimon * we must make sure the trailer is rewritten on append, ar_next() 463194206Ssimon * will stop us if the archive containing the trailer was not written 464194206Ssimon */ 465194206Ssimon wr_trail = 0; 466194206Ssimon 467194206Ssimon /* 468194206Ssimon * Add any device dependent code as required here 469194206Ssimon */ 470194206Ssimon if (artyp != ISREG) 471194206Ssimon return(0); 472194206Ssimon /* 473194206Ssimon * Ok we have an archive in a regular file. If we were rewriting a 474194206Ssimon * file, we must get rid of all the stuff after the current offset 475194206Ssimon * (it was not written by pax). 476194206Ssimon */ 477194206Ssimon if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) || 478194206Ssimon (ftruncate(arfd, cpos) < 0)) { 479194206Ssimon syswarn(1, errno, "Unable to truncate archive file"); 480194206Ssimon return(-1); 481194206Ssimon } 482194206Ssimon return(0); 483194206Ssimon} 484194206Ssimon 485194206Ssimon/* 486194206Ssimon * ar_app_ok() 487194206Ssimon * check if the last volume in the archive allows appends. We cannot check 488194206Ssimon * this until we are ready to write since there is no spec that says all 489194206Ssimon * volumes in a single archive have to be of the same type... 490194206Ssimon * Return: 491194206Ssimon * 0 if we can append, -1 otherwise. 492194206Ssimon */ 493194206Ssimon 494194206Ssimonint 495194206Ssimonar_app_ok(void) 496194206Ssimon{ 497194206Ssimon if (artyp == ISPIPE) { 498194206Ssimon paxwarn(1, "Cannot append to an archive obtained from a pipe."); 499194206Ssimon return(-1); 500194206Ssimon } 501194206Ssimon 502194206Ssimon if (!invld_rec) 503194206Ssimon return(0); 504194206Ssimon paxwarn(1,"Cannot append, device record size %d does not support %s spec", 505194206Ssimon rdblksz, argv0); 506194206Ssimon return(-1); 507194206Ssimon} 508194206Ssimon 509194206Ssimon/* 510194206Ssimon * ar_read() 511194206Ssimon * read up to a specified number of bytes from the archive into the 512194206Ssimon * supplied buffer. When dealing with tapes we may not always be able to 513194206Ssimon * read what we want. 514194206Ssimon * Return: 515194206Ssimon * Number of bytes in buffer. 0 for end of file, -1 for a read error. 516194206Ssimon */ 517194206Ssimon 518194206Ssimonint 519194206Ssimonar_read(char *buf, int cnt) 520194206Ssimon{ 521194206Ssimon int res = 0; 522194206Ssimon 523194206Ssimon /* 524194206Ssimon * if last i/o was in error, no more reads until reset or new volume 525194206Ssimon */ 526194206Ssimon if (lstrval <= 0) 527194206Ssimon return(lstrval); 528194206Ssimon 529194206Ssimon /* 530194206Ssimon * how we read must be based on device type 531194206Ssimon */ 532194206Ssimon switch (artyp) { 533194206Ssimon case ISTAPE: 534194206Ssimon if ((res = read(arfd, buf, cnt)) > 0) { 535194206Ssimon /* 536194206Ssimon * CAUTION: tape systems may not always return the same 537194206Ssimon * sized records so we leave blksz == MAXBLK. The 538194206Ssimon * physical record size that a tape drive supports is 539194206Ssimon * very hard to determine in a uniform and portable 540194206Ssimon * manner. 541194206Ssimon */ 542194206Ssimon io_ok = 1; 543194206Ssimon if (res != rdblksz) { 544194206Ssimon /* 545194206Ssimon * Record size changed. If this is happens on 546194206Ssimon * any record after the first, we probably have 547194206Ssimon * a tape drive which has a fixed record size 548194206Ssimon * we are getting multiple records in a single 549194206Ssimon * read). Watch out for record blocking that 550194206Ssimon * violates pax spec (must be a multiple of 551194206Ssimon * BLKMULT). 552194206Ssimon */ 553194206Ssimon rdblksz = res; 554194206Ssimon if (rdblksz % BLKMULT) 555194206Ssimon invld_rec = 1; 556194206Ssimon } 557194206Ssimon return(res); 558194206Ssimon } 559194206Ssimon break; 560194206Ssimon case ISREG: 561194206Ssimon case ISBLK: 562194206Ssimon case ISCHR: 563194206Ssimon case ISPIPE: 564194206Ssimon default: 565194206Ssimon /* 566194206Ssimon * Files are so easy to deal with. These other things cannot 567194206Ssimon * be trusted at all. So when we are dealing with character 568194206Ssimon * devices and pipes we just take what they have ready for us 569194206Ssimon * and return. Trying to do anything else with them runs the 570194206Ssimon * risk of failure. 571194206Ssimon */ 572194206Ssimon if ((res = read(arfd, buf, cnt)) > 0) { 573194206Ssimon io_ok = 1; 574194206Ssimon return(res); 575194206Ssimon } 576194206Ssimon break; 577194206Ssimon } 578194206Ssimon 579194206Ssimon /* 580194206Ssimon * We are in trouble at this point, something is broken... 581194206Ssimon */ 582194206Ssimon lstrval = res; 583194206Ssimon if (res < 0) 584194206Ssimon syswarn(1, errno, "Failed read on archive volume %d", arvol); 585194206Ssimon else 586194206Ssimon paxwarn(0, "End of archive volume %d reached", arvol); 587194206Ssimon return(res); 588194206Ssimon} 589194206Ssimon 590194206Ssimon/* 591194206Ssimon * ar_write() 592194206Ssimon * Write a specified number of bytes in supplied buffer to the archive 593194206Ssimon * device so it appears as a single "block". Deals with errors and tries 594194206Ssimon * to recover when faced with short writes. 595194206Ssimon * Return: 596194206Ssimon * Number of bytes written. 0 indicates end of volume reached and with no 597194206Ssimon * flaws (as best that can be detected). A -1 indicates an unrecoverable 598194206Ssimon * error in the archive occured. 599194206Ssimon */ 600194206Ssimon 601194206Ssimonint 602194206Ssimonar_write(char *buf, int bsz) 603194206Ssimon{ 604194206Ssimon int res; 605194206Ssimon off_t cpos; 606194206Ssimon 607194206Ssimon /* 608194206Ssimon * do not allow pax to create a "bad" archive. Once a write fails on 609194206Ssimon * an archive volume prevent further writes to it. 610194206Ssimon */ 611194206Ssimon if (lstrval <= 0) 612194206Ssimon return(lstrval); 613194206Ssimon 614194206Ssimon if ((res = write(arfd, buf, bsz)) == bsz) { 615194206Ssimon wr_trail = 1; 616194206Ssimon io_ok = 1; 617194206Ssimon return(bsz); 618194206Ssimon } 619194206Ssimon /* 620194206Ssimon * write broke, see what we can do with it. We try to send any partial 621194206Ssimon * writes that may violate pax spec to the next archive volume. 622194206Ssimon */ 623194206Ssimon if (res < 0) 624194206Ssimon lstrval = res; 625194206Ssimon else 626194206Ssimon lstrval = 0; 627194206Ssimon 628194206Ssimon switch (artyp) { 629194206Ssimon case ISREG: 630194206Ssimon if ((res > 0) && (res % BLKMULT)) { 631194206Ssimon /* 632194206Ssimon * try to fix up partial writes which are not BLKMULT 633194206Ssimon * in size by forcing the runt record to next archive 634194206Ssimon * volume 635194206Ssimon */ 636194206Ssimon if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 637194206Ssimon break; 638194206Ssimon cpos -= (off_t)res; 639194206Ssimon if (ftruncate(arfd, cpos) < 0) 640194206Ssimon break; 641194206Ssimon res = lstrval = 0; 642194206Ssimon break; 643194206Ssimon } 644194206Ssimon if (res >= 0) 645194206Ssimon break; 646194206Ssimon /* 647194206Ssimon * if file is out of space, handle it like a return of 0 648194206Ssimon */ 649194206Ssimon if ((errno == ENOSPC) || (errno == EFBIG) || (errno == EDQUOT)) 650194206Ssimon res = lstrval = 0; 651194206Ssimon break; 652194206Ssimon case ISTAPE: 653194206Ssimon case ISCHR: 654194206Ssimon case ISBLK: 655194206Ssimon if (res >= 0) 656194206Ssimon break; 657194206Ssimon if (errno == EACCES) { 658194206Ssimon paxwarn(0, "Write failed, archive is write protected."); 659194206Ssimon res = lstrval = 0; 660194206Ssimon return(0); 661194206Ssimon } 662194206Ssimon /* 663194206Ssimon * see if we reached the end of media, if so force a change to 664194206Ssimon * the next volume 665194206Ssimon */ 666194206Ssimon if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO)) 667194206Ssimon res = lstrval = 0; 668194206Ssimon break; 669194206Ssimon case ISPIPE: 670194206Ssimon default: 671194206Ssimon /* 672194206Ssimon * we cannot fix errors to these devices 673194206Ssimon */ 674194206Ssimon break; 675194206Ssimon } 676194206Ssimon 677194206Ssimon /* 678194206Ssimon * Better tell the user the bad news... 679194206Ssimon * if this is a block aligned archive format, we may have a bad archive 680194206Ssimon * if the format wants the header to start at a BLKMULT boundary. While 681194206Ssimon * we can deal with the mis-aligned data, it violates spec and other 682194206Ssimon * archive readers will likely fail. if the format is not block 683194206Ssimon * aligned, the user may be lucky (and the archive is ok). 684194206Ssimon */ 685194206Ssimon if (res >= 0) { 686194206Ssimon if (res > 0) 687194206Ssimon wr_trail = 1; 688194206Ssimon io_ok = 1; 689194206Ssimon } 690194206Ssimon 691194206Ssimon /* 692194206Ssimon * If we were trying to rewrite the trailer and it didn't work, we 693194206Ssimon * must quit right away. 694194206Ssimon */ 695194206Ssimon if (!wr_trail && (res <= 0)) { 696194206Ssimon paxwarn(1,"Unable to append, trailer re-write failed. Quitting."); 697194206Ssimon return(res); 698194206Ssimon } 699194206Ssimon 700194206Ssimon if (res == 0) 701194206Ssimon paxwarn(0, "End of archive volume %d reached", arvol); 702194206Ssimon else if (res < 0) 703194206Ssimon syswarn(1, errno, "Failed write to archive volume: %d", arvol); 704194206Ssimon else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0)) 705194206Ssimon paxwarn(0,"WARNING: partial archive write. Archive MAY BE FLAWED"); 706194206Ssimon else 707194206Ssimon paxwarn(1,"WARNING: partial archive write. Archive IS FLAWED"); 708194206Ssimon return(res); 709194206Ssimon} 710194206Ssimon 711194206Ssimon/* 712194206Ssimon * ar_rdsync() 713194206Ssimon * Try to move past a bad spot on a flawed archive as needed to continue 714194206Ssimon * I/O. Clears error flags to allow I/O to continue. 715194206Ssimon * Return: 716194206Ssimon * 0 when ok to try i/o again, -1 otherwise. 717194206Ssimon */ 718194206Ssimon 719194206Ssimonint 720194206Ssimonar_rdsync(void) 721194206Ssimon{ 722194206Ssimon long fsbz; 723194206Ssimon off_t cpos; 724194206Ssimon off_t mpos; 725194206Ssimon struct mtop mb; 726194206Ssimon 727194206Ssimon /* 728194206Ssimon * Fail resync attempts at user request (done) or this is going to be 729194206Ssimon * an update/append to an existing archive. If last i/o hit media end, 730194206Ssimon * we need to go to the next volume not try a resync. 731194206Ssimon */ 732194206Ssimon if ((done > 0) || (lstrval == 0)) 733194206Ssimon return(-1); 734194206Ssimon 735194206Ssimon if ((act == APPND) || (act == ARCHIVE)) { 736194206Ssimon paxwarn(1, "Cannot allow updates to an archive with flaws."); 737194206Ssimon return(-1); 738194206Ssimon } 739194206Ssimon if (io_ok) 740194206Ssimon did_io = 1; 741194206Ssimon 742194206Ssimon switch(artyp) { 743194206Ssimon case ISTAPE: 744194206Ssimon /* 745194206Ssimon * if the last i/o was a successful data transfer, we assume 746194206Ssimon * the fault is just a bad record on the tape that we are now 747194206Ssimon * past. If we did not get any data since the last resync try 748194206Ssimon * to move the tape forward one PHYSICAL record past any 749194206Ssimon * damaged tape section. Some tape drives are stubborn and need 750194206Ssimon * to be pushed. 751194206Ssimon */ 752194206Ssimon if (io_ok) { 753194206Ssimon io_ok = 0; 754194206Ssimon lstrval = 1; 755194206Ssimon break; 756194206Ssimon } 757194206Ssimon mb.mt_op = MTFSR; 758194206Ssimon mb.mt_count = 1; 759194206Ssimon if (ioctl(arfd, MTIOCTOP, &mb) < 0) 760194206Ssimon break; 761194206Ssimon lstrval = 1; 762194206Ssimon break; 763194206Ssimon case ISREG: 764194206Ssimon case ISCHR: 765194206Ssimon case ISBLK: 766194206Ssimon /* 767194206Ssimon * try to step over the bad part of the device. 768194206Ssimon */ 769194206Ssimon io_ok = 0; 770194206Ssimon if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG)) 771194206Ssimon fsbz = BLKMULT; 772194206Ssimon if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) 773194206Ssimon break; 774194206Ssimon mpos = fsbz - (cpos % (off_t)fsbz); 775194206Ssimon if (lseek(arfd, mpos, SEEK_CUR) < 0) 776194206Ssimon break; 777194206Ssimon lstrval = 1; 778194206Ssimon break; 779194206Ssimon case ISPIPE: 780194206Ssimon default: 781194206Ssimon /* 782194206Ssimon * cannot recover on these archive device types 783194206Ssimon */ 784194206Ssimon io_ok = 0; 785194206Ssimon break; 786194206Ssimon } 787194206Ssimon if (lstrval <= 0) { 788194206Ssimon paxwarn(1, "Unable to recover from an archive read failure."); 789194206Ssimon return(-1); 790194206Ssimon } 791194206Ssimon paxwarn(0, "Attempting to recover from an archive read failure."); 792194206Ssimon return(0); 793194206Ssimon} 794194206Ssimon 795194206Ssimon/* 796194206Ssimon * ar_fow() 797194206Ssimon * Move the I/O position within the archive foward the specified number of 798194206Ssimon * bytes as supported by the device. If we cannot move the requested 799194206Ssimon * number of bytes, return the actual number of bytes moved in skipped. 800194206Ssimon * Return: 801194206Ssimon * 0 if moved the requested distance, -1 on complete failure, 1 on 802194206Ssimon * partial move (the amount moved is in skipped) 803194206Ssimon */ 804194206Ssimon 805194206Ssimonint 806194206Ssimonar_fow(off_t sksz, off_t *skipped) 807194206Ssimon{ 808194206Ssimon off_t cpos; 809194206Ssimon off_t mpos; 810194206Ssimon 811194206Ssimon *skipped = 0; 812194206Ssimon if (sksz <= 0) 813194206Ssimon return(0); 814194206Ssimon 815194206Ssimon /* 816194206Ssimon * we cannot move foward at EOF or error 817194206Ssimon */ 818194206Ssimon if (lstrval <= 0) 819194206Ssimon return(lstrval); 820194206Ssimon 821194206Ssimon /* 822194206Ssimon * Safer to read forward on devices where it is hard to find the end of 823194206Ssimon * the media without reading to it. With tapes we cannot be sure of the 824194206Ssimon * number of physical blocks to skip (we do not know physical block 825194206Ssimon * size at this point), so we must only read foward on tapes! 826194206Ssimon */ 827194206Ssimon if (artyp != ISREG) 828194206Ssimon return(0); 829194206Ssimon 830194206Ssimon /* 831194206Ssimon * figure out where we are in the archive 832194206Ssimon */ 833194206Ssimon if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) { 834194206Ssimon /* 835194206Ssimon * we can be asked to move farther than there are bytes in this 836194206Ssimon * volume, if so, just go to file end and let normal buf_fill() 837194206Ssimon * deal with the end of file (it will go to next volume by 838194206Ssimon * itself) 839194206Ssimon */ 840194206Ssimon if ((mpos = cpos + sksz) > arsb.st_size) { 841194206Ssimon *skipped = arsb.st_size - cpos; 842194206Ssimon mpos = arsb.st_size; 843194206Ssimon } else 844194206Ssimon *skipped = sksz; 845194206Ssimon if (lseek(arfd, mpos, SEEK_SET) >= 0) 846194206Ssimon return(0); 847194206Ssimon } 848194206Ssimon syswarn(1, errno, "Forward positioning operation on archive failed"); 849194206Ssimon lstrval = -1; 850194206Ssimon return(-1); 851194206Ssimon} 852194206Ssimon 853194206Ssimon/* 854194206Ssimon * ar_rev() 855194206Ssimon * move the i/o position within the archive backwards the specified byte 856194206Ssimon * count as supported by the device. With tapes drives we RESET rdblksz to 857194206Ssimon * the PHYSICAL blocksize. 858194206Ssimon * NOTE: We should only be called to move backwards so we can rewrite the 859194206Ssimon * last records (the trailer) of an archive (APPEND). 860194206Ssimon * Return: 861194206Ssimon * 0 if moved the requested distance, -1 on complete failure 862194206Ssimon */ 863194206Ssimon 864194206Ssimonint 865194206Ssimonar_rev(off_t sksz) 866194206Ssimon{ 867194206Ssimon off_t cpos; 868194206Ssimon struct mtop mb; 869194206Ssimon int phyblk; 870194206Ssimon 871194206Ssimon /* 872194206Ssimon * make sure we do not have try to reverse on a flawed archive 873194206Ssimon */ 874194206Ssimon if (lstrval < 0) 875194206Ssimon return(lstrval); 876194206Ssimon 877194206Ssimon switch(artyp) { 878194206Ssimon case ISPIPE: 879 if (sksz <= 0) 880 break; 881 /* 882 * cannot go backwards on these critters 883 */ 884 paxwarn(1, "Reverse positioning on pipes is not supported."); 885 lstrval = -1; 886 return(-1); 887 case ISREG: 888 case ISBLK: 889 case ISCHR: 890 default: 891 if (sksz <= 0) 892 break; 893 894 /* 895 * For things other than files, backwards movement has a very 896 * high probability of failure as we really do not know the 897 * true attributes of the device we are talking to (the device 898 * may not even have the ability to lseek() in any direction). 899 * First we figure out where we are in the archive. 900 */ 901 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) { 902 syswarn(1, errno, 903 "Unable to obtain current archive byte offset"); 904 lstrval = -1; 905 return(-1); 906 } 907 908 /* 909 * we may try to go backwards past the start when the archive 910 * is only a single record. If this hapens and we are on a 911 * multi volume archive, we need to go to the end of the 912 * previous volume and continue our movement backwards from 913 * there. 914 */ 915 if ((cpos -= sksz) < (off_t)0L) { 916 if (arvol > 1) { 917 /* 918 * this should never happen 919 */ 920 paxwarn(1,"Reverse position on previous volume."); 921 lstrval = -1; 922 return(-1); 923 } 924 cpos = (off_t)0L; 925 } 926 if (lseek(arfd, cpos, SEEK_SET) < 0) { 927 syswarn(1, errno, "Unable to seek archive backwards"); 928 lstrval = -1; 929 return(-1); 930 } 931 break; 932 case ISTAPE: 933 /* 934 * Calculate and move the proper number of PHYSICAL tape 935 * blocks. If the sksz is not an even multiple of the physical 936 * tape size, we cannot do the move (this should never happen). 937 * (We also cannot handler trailers spread over two vols). 938 * get_phys() also makes sure we are in front of the filemark. 939 */ 940 if ((phyblk = get_phys()) <= 0) { 941 lstrval = -1; 942 return(-1); 943 } 944 945 /* 946 * make sure future tape reads only go by physical tape block 947 * size (set rdblksz to the real size). 948 */ 949 rdblksz = phyblk; 950 951 /* 952 * if no movement is required, just return (we must be after 953 * get_phys() so the physical blocksize is properly set) 954 */ 955 if (sksz <= 0) 956 break; 957 958 /* 959 * ok we have to move. Make sure the tape drive can do it. 960 */ 961 if (sksz % phyblk) { 962 paxwarn(1, 963 "Tape drive unable to backspace requested amount"); 964 lstrval = -1; 965 return(-1); 966 } 967 968 /* 969 * move backwards the requested number of bytes 970 */ 971 mb.mt_op = MTBSR; 972 mb.mt_count = sksz/phyblk; 973 if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 974 syswarn(1,errno, "Unable to backspace tape %d blocks.", 975 mb.mt_count); 976 lstrval = -1; 977 return(-1); 978 } 979 break; 980 } 981 lstrval = 1; 982 return(0); 983} 984 985/* 986 * get_phys() 987 * Determine the physical block size on a tape drive. We need the physical 988 * block size so we know how many bytes we skip over when we move with 989 * mtio commands. We also make sure we are BEFORE THE TAPE FILEMARK when 990 * return. 991 * This is one really SLOW routine... 992 * Return: 993 * physical block size if ok (ok > 0), -1 otherwise 994 */ 995 996static int 997get_phys(void) 998{ 999 int padsz = 0; 1000 int res; 1001 int phyblk; 1002 struct mtop mb; 1003 char scbuf[MAXBLK]; 1004 1005 /* 1006 * move to the file mark, and then back up one record and read it. 1007 * this should tell us the physical record size the tape is using. 1008 */ 1009 if (lstrval == 1) { 1010 /* 1011 * we know we are at file mark when we get back a 0 from 1012 * read() 1013 */ 1014 while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) 1015 padsz += res; 1016 if (res < 0) { 1017 syswarn(1, errno, "Unable to locate tape filemark."); 1018 return(-1); 1019 } 1020 } 1021 1022 /* 1023 * move backwards over the file mark so we are at the end of the 1024 * last record. 1025 */ 1026 mb.mt_op = MTBSF; 1027 mb.mt_count = 1; 1028 if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 1029 syswarn(1, errno, "Unable to backspace over tape filemark."); 1030 return(-1); 1031 } 1032 1033 /* 1034 * move backwards so we are in front of the last record and read it to 1035 * get physical tape blocksize. 1036 */ 1037 mb.mt_op = MTBSR; 1038 mb.mt_count = 1; 1039 if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 1040 syswarn(1, errno, "Unable to backspace over last tape block."); 1041 return(-1); 1042 } 1043 if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) { 1044 syswarn(1, errno, "Cannot determine archive tape blocksize."); 1045 return(-1); 1046 } 1047 1048 /* 1049 * read foward to the file mark, then back up in front of the filemark 1050 * (this is a bit paranoid, but should be safe to do). 1051 */ 1052 while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0) 1053 ; 1054 if (res < 0) { 1055 syswarn(1, errno, "Unable to locate tape filemark."); 1056 return(-1); 1057 } 1058 mb.mt_op = MTBSF; 1059 mb.mt_count = 1; 1060 if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 1061 syswarn(1, errno, "Unable to backspace over tape filemark."); 1062 return(-1); 1063 } 1064 1065 /* 1066 * set lstrval so we know that the filemark has not been seen 1067 */ 1068 lstrval = 1; 1069 1070 /* 1071 * return if there was no padding 1072 */ 1073 if (padsz == 0) 1074 return(phyblk); 1075 1076 /* 1077 * make sure we can move backwards over the padding. (this should 1078 * never fail). 1079 */ 1080 if (padsz % phyblk) { 1081 paxwarn(1, "Tape drive unable to backspace requested amount"); 1082 return(-1); 1083 } 1084 1085 /* 1086 * move backwards over the padding so the head is where it was when 1087 * we were first called (if required). 1088 */ 1089 mb.mt_op = MTBSR; 1090 mb.mt_count = padsz/phyblk; 1091 if (ioctl(arfd, MTIOCTOP, &mb) < 0) { 1092 syswarn(1,errno,"Unable to backspace tape over %d pad blocks", 1093 mb.mt_count); 1094 return(-1); 1095 } 1096 return(phyblk); 1097} 1098 1099/* 1100 * ar_next() 1101 * prompts the user for the next volume in this archive. For some devices 1102 * we may allow the media to be changed. Otherwise a new archive is 1103 * prompted for. By pax spec, if there is no controlling tty or an eof is 1104 * read on tty input, we must quit pax. 1105 * Return: 1106 * 0 when ready to continue, -1 when all done 1107 */ 1108 1109int 1110ar_next(void) 1111{ 1112 char buf[PAXPATHLEN+2]; 1113 static int freeit = 0; 1114 sigset_t o_mask; 1115 1116 /* 1117 * WE MUST CLOSE THE DEVICE. A lot of devices must see last close, (so 1118 * things like writing EOF etc will be done) (Watch out ar_close() can 1119 * also be called via a signal handler, so we must prevent a race. 1120 */ 1121 if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0) 1122 syswarn(0, errno, "Unable to set signal mask"); 1123 ar_close(); 1124 if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0) 1125 syswarn(0, errno, "Unable to restore signal mask"); 1126 1127 if (done || !wr_trail || strcmp(NM_TAR, argv0) == 0) 1128 return(-1); 1129 1130 tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0); 1131 1132 /* 1133 * if i/o is on stdin or stdout, we cannot reopen it (we do not know 1134 * the name), the user will be forced to type it in. 1135 */ 1136 if (strcmp(arcname, stdo) && strcmp(arcname, stdn) && (artyp != ISREG) 1137 && (artyp != ISPIPE)) { 1138 if (artyp == ISTAPE) { 1139 tty_prnt("%s ready for archive tape volume: %d\n", 1140 arcname, arvol); 1141 tty_prnt("Load the NEXT TAPE on the tape drive"); 1142 } else { 1143 tty_prnt("%s ready for archive volume: %d\n", 1144 arcname, arvol); 1145 tty_prnt("Load the NEXT STORAGE MEDIA (if required)"); 1146 } 1147 1148 if ((act == ARCHIVE) || (act == APPND)) 1149 tty_prnt(" and make sure it is WRITE ENABLED.\n"); 1150 else 1151 tty_prnt("\n"); 1152 1153 for(;;) { 1154 tty_prnt("Type \"y\" to continue, \".\" to quit %s,", 1155 argv0); 1156 tty_prnt(" or \"s\" to switch to new device.\nIf you"); 1157 tty_prnt(" cannot change storage media, type \"s\"\n"); 1158 tty_prnt("Is the device ready and online? > "); 1159 1160 if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){ 1161 done = 1; 1162 lstrval = -1; 1163 tty_prnt("Quitting %s!\n", argv0); 1164 vfpart = 0; 1165 return(-1); 1166 } 1167 1168 if ((buf[0] == '\0') || (buf[1] != '\0')) { 1169 tty_prnt("%s unknown command, try again\n",buf); 1170 continue; 1171 } 1172 1173 switch (buf[0]) { 1174 case 'y': 1175 case 'Y': 1176 /* 1177 * we are to continue with the same device 1178 */ 1179 if (ar_open(arcname) >= 0) 1180 return(0); 1181 tty_prnt("Cannot re-open %s, try again\n", 1182 arcname); 1183 continue; 1184 case 's': 1185 case 'S': 1186 /* 1187 * user wants to open a different device 1188 */ 1189 tty_prnt("Switching to a different archive\n"); 1190 break; 1191 default: 1192 tty_prnt("%s unknown command, try again\n",buf); 1193 continue; 1194 } 1195 break; 1196 } 1197 } else 1198 tty_prnt("Ready for archive volume: %d\n", arvol); 1199 1200 /* 1201 * have to go to a different archive 1202 */ 1203 for (;;) { 1204 tty_prnt("Input archive name or \".\" to quit %s.\n", argv0); 1205 tty_prnt("Archive name > "); 1206 1207 if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) { 1208 done = 1; 1209 lstrval = -1; 1210 tty_prnt("Quitting %s!\n", argv0); 1211 vfpart = 0; 1212 return(-1); 1213 } 1214 if (buf[0] == '\0') { 1215 tty_prnt("Empty file name, try again\n"); 1216 continue; 1217 } 1218 if (!strcmp(buf, "..")) { 1219 tty_prnt("Illegal file name: .. try again\n"); 1220 continue; 1221 } 1222 if (strlen(buf) > PAXPATHLEN) { 1223 tty_prnt("File name too long, try again\n"); 1224 continue; 1225 } 1226 1227 /* 1228 * try to open new archive 1229 */ 1230 if (ar_open(buf) >= 0) { 1231 if (freeit) { 1232 (void)free((char *)(uintptr_t)arcname); 1233 freeit = 0; 1234 } 1235 if ((arcname = strdup(buf)) == NULL) { 1236 done = 1; 1237 lstrval = -1; 1238 paxwarn(0, "Cannot save archive name."); 1239 return(-1); 1240 } 1241 freeit = 1; 1242 break; 1243 } 1244 tty_prnt("Cannot open %s, try again\n", buf); 1245 continue; 1246 } 1247 return(0); 1248} 1249 1250/* 1251 * ar_start_gzip() 1252 * starts the gzip compression/decompression process as a child, using magic 1253 * to keep the fd the same in the calling function (parent). 1254 */ 1255void 1256ar_start_gzip(int fd, const char *gzip_prog, int wr) 1257{ 1258 int fds[2]; 1259 const char *gzip_flags; 1260 1261 if (pipe(fds) < 0) 1262 err(1, "could not pipe"); 1263 zpid = fork(); 1264 if (zpid < 0) 1265 err(1, "could not fork"); 1266 1267 /* parent */ 1268 if (zpid) { 1269 if (wr) 1270 dup2(fds[1], fd); 1271 else 1272 dup2(fds[0], fd); 1273 close(fds[0]); 1274 close(fds[1]); 1275 } else { 1276 if (wr) { 1277 dup2(fds[0], STDIN_FILENO); 1278 dup2(fd, STDOUT_FILENO); 1279 gzip_flags = "-c"; 1280 } else { 1281 dup2(fds[1], STDOUT_FILENO); 1282 dup2(fd, STDIN_FILENO); 1283 gzip_flags = "-dc"; 1284 } 1285 close(fds[0]); 1286 close(fds[1]); 1287 if (execlp(gzip_prog, gzip_prog, gzip_flags, 1288 (char *)NULL) < 0) 1289 err(1, "could not exec"); 1290 /* NOTREACHED */ 1291 } 1292} 1293