pax.c revision 281661
11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1992 Keith Muller. 31556Srgrimes * Copyright (c) 1992, 1993 41556Srgrimes * The Regents of the University of California. All rights reserved. 51556Srgrimes * 61556Srgrimes * This code is derived from software contributed to Berkeley by 71556Srgrimes * Keith Muller of the University of California, San Diego. 81556Srgrimes * 91556Srgrimes * Redistribution and use in source and binary forms, with or without 101556Srgrimes * modification, are permitted provided that the following conditions 111556Srgrimes * are met: 121556Srgrimes * 1. Redistributions of source code must retain the above copyright 131556Srgrimes * notice, this list of conditions and the following disclaimer. 141556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151556Srgrimes * notice, this list of conditions and the following disclaimer in the 161556Srgrimes * documentation and/or other materials provided with the distribution. 171556Srgrimes * 4. Neither the name of the University nor the names of its contributors 181556Srgrimes * may be used to endorse or promote products derived from this software 191556Srgrimes * without specific prior written permission. 201556Srgrimes * 211556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311556Srgrimes * SUCH DAMAGE. 321556Srgrimes */ 331556Srgrimes 34114470Sobrien#if 0 351556Srgrimes#ifndef lint 3620420Sstevestatic char const copyright[] = 371556Srgrimes"@(#) Copyright (c) 1992, 1993\n\ 381556Srgrimes The Regents of the University of California. All rights reserved.\n"; 391556Srgrimes#endif /* not lint */ 401556Srgrimes 411556Srgrimes#ifndef lint 4236049Scharnierstatic char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94"; 43114470Sobrien#endif /* not lint */ 4436049Scharnier#endif 4599110Sobrien#include <sys/cdefs.h> 4699110Sobrien__FBSDID("$FreeBSD: stable/10/bin/pax/pax.c 281661 2015-04-17 18:33:59Z eadler $"); 471556Srgrimes 481556Srgrimes#include <sys/types.h> 491556Srgrimes#include <sys/stat.h> 501556Srgrimes#include <sys/time.h> 511556Srgrimes#include <sys/resource.h> 5276286Skris#include <err.h> 5331666Seivind#include <errno.h> 5476351Skris#include <fcntl.h> 5531666Seivind#include <locale.h> 5676016Skris#include <paths.h> 571556Srgrimes#include <signal.h> 5831666Seivind#include <stdio.h> 5931666Seivind#include <stdlib.h> 6078732Sdd#include <string.h> 611556Srgrimes#include <unistd.h> 621556Srgrimes#include "pax.h" 631556Srgrimes#include "extern.h" 6490110Simpstatic int gen_init(void); 651556Srgrimes 661556Srgrimes/* 671556Srgrimes * PAX main routines, general globals and some simple start up routines 681556Srgrimes */ 691556Srgrimes 701556Srgrimes/* 711556Srgrimes * Variables that can be accessed by any routine within pax 721556Srgrimes */ 731556Srgrimesint act = DEFOP; /* read/write/append/copy */ 741556SrgrimesFSUB *frmt = NULL; /* archive format type */ 751556Srgrimesint cflag; /* match all EXCEPT pattern/file */ 7676351Skrisint cwdfd; /* starting cwd */ 771556Srgrimesint dflag; /* directory member match only */ 781556Srgrimesint iflag; /* interactive file/archive rename */ 791556Srgrimesint kflag; /* do not overwrite existing files */ 801556Srgrimesint lflag; /* use hard links when possible */ 811556Srgrimesint nflag; /* select first archive member match */ 821556Srgrimesint tflag; /* restore access time after read */ 831556Srgrimesint uflag; /* ignore older modification time files */ 841556Srgrimesint vflag; /* produce verbose output */ 851556Srgrimesint Dflag; /* same as uflag except inode change time */ 861556Srgrimesint Hflag; /* follow command line symlinks (write only) */ 871556Srgrimesint Lflag; /* follow symlinks when writing */ 88281661Seadlerint Oflag; /* limit to single volume */ 891556Srgrimesint Xflag; /* archive files with same device id only */ 901556Srgrimesint Yflag; /* same as Dflg except after name mode */ 911556Srgrimesint Zflag; /* same as uflg except after name mode */ 921556Srgrimesint vfpart; /* is partial verbose output in progress */ 931556Srgrimesint patime = 1; /* preserve file access time */ 941556Srgrimesint pmtime = 1; /* preserve file modification times */ 9576351Skrisint nodirs; /* do not create directories as needed */ 961556Srgrimesint pmode; /* preserve file mode bits */ 971556Srgrimesint pids; /* preserve file uid/gid */ 9876351Skrisint rmleadslash = 0; /* remove leading '/' from pathnames */ 991556Srgrimesint exit_val; /* exit value */ 1001556Srgrimesint docrc; /* check/create file crc */ 1011556Srgrimeschar *dirptr; /* destination dir in a copy */ 102114583Smarkmconst char *argv0; /* root of argv[0] */ 10376351Skrissigset_t s_mask; /* signal mask for cleanup critical sect */ 10481601SpeterFILE *listf; /* file pointer to print file list to */ 10576016Skrischar *tempfile; /* tempfile to use for mkstemp(3) */ 10676016Skrischar *tempbase; /* basename of tempfile to use for mkstemp(3) */ 1071556Srgrimes 1081556Srgrimes/* 1091556Srgrimes * PAX - Portable Archive Interchange 1101556Srgrimes * 1111556Srgrimes * A utility to read, write, and write lists of the members of archive 1121556Srgrimes * files and copy directory hierarchies. A variety of archive formats 1131556Srgrimes * are supported (some are described in POSIX 1003.1 10.1): 1141556Srgrimes * 1151556Srgrimes * ustar - 10.1.1 extended tar interchange format 1161556Srgrimes * cpio - 10.1.2 extended cpio interchange format 1171556Srgrimes * tar - old BSD 4.3 tar format 1181556Srgrimes * binary cpio - old cpio with binary header format 1191556Srgrimes * sysVR4 cpio - with and without CRC 1201556Srgrimes * 1211556Srgrimes * This version is a superset of IEEE Std 1003.2b-d3 1221556Srgrimes * 1231556Srgrimes * Summary of Extensions to the IEEE Standard: 1241556Srgrimes * 1251556Srgrimes * 1 READ ENHANCEMENTS 1261556Srgrimes * 1.1 Operations which read archives will continue to operate even when 1278855Srgrimes * processing archives which may be damaged, truncated, or fail to meet 1281556Srgrimes * format specs in several different ways. Damaged sections of archives 1291556Srgrimes * are detected and avoided if possible. Attempts will be made to resync 1301556Srgrimes * archive read operations even with badly damaged media. 1311556Srgrimes * 1.2 Blocksize requirements are not strictly enforced on archive read. 1321556Srgrimes * Tapes which have variable sized records can be read without errors. 1331556Srgrimes * 1.3 The user can specify via the non-standard option flag -E if error 1341556Srgrimes * resync operation should stop on a media error, try a specified number 1351556Srgrimes * of times to correct, or try to correct forever. 1361556Srgrimes * 1.4 Sparse files (lseek holes) stored on the archive (but stored with blocks 1371556Srgrimes * of all zeros will be restored with holes appropriate for the target 138102230Strhodes * file system 1391556Srgrimes * 1.5 The user is notified whenever something is found during archive 1401556Srgrimes * read operations which violates spec (but the read will continue). 1411556Srgrimes * 1.6 Multiple archive volumes can be read and may span over different 1428855Srgrimes * archive devices 1431556Srgrimes * 1.7 Rigidly restores all file attributes exactly as they are stored on the 1441556Srgrimes * archive. 1451556Srgrimes * 1.8 Modification change time ranges can be specified via multiple -T 1461556Srgrimes * options. These allow a user to select files whose modification time 1471556Srgrimes * lies within a specific time range. 1481556Srgrimes * 1.9 Files can be selected based on owner (user name or uid) via one or more 1491556Srgrimes * -U options. 1501556Srgrimes * 1.10 Files can be selected based on group (group name or gid) via one o 1511556Srgrimes * more -G options. 15246684Skris * 1.11 File modification time can be checked against existing file after 1531556Srgrimes * name modification (-Z) 1541556Srgrimes * 1551556Srgrimes * 2 WRITE ENHANCEMENTS 1561556Srgrimes * 2.1 Write operation will stop instead of allowing a user to create a flawed 1571556Srgrimes * flawed archive (due to any problem). 15846684Skris * 2.2 Archives written by pax are forced to strictly conform to both the 15946684Skris * archive and pax the specific format specifications. 1601556Srgrimes * 2.3 Blocking size and format is rigidly enforced on writes. 1611556Srgrimes * 2.4 Formats which may exhibit header overflow problems (they have fields 162102230Strhodes * too small for large file systems, such as inode number storage), use 1631556Srgrimes * routines designed to repair this problem. These techniques still 1641556Srgrimes * conform to both pax and format specifications, but no longer truncate 1651556Srgrimes * these fields. This removes any restrictions on using these archive 166102230Strhodes * formats on large file systems. 1671556Srgrimes * 2.5 Multiple archive volumes can be written and may span over different 1688855Srgrimes * archive devices 1691556Srgrimes * 2.6 A archive volume record limit allows the user to specify the number 1701556Srgrimes * of bytes stored on an archive volume. When reached the user is 1711556Srgrimes * prompted for the next archive volume. This is specified with the 17246684Skris * non-standard -B flag. The limit is rounded up to the next blocksize. 1731556Srgrimes * 2.7 All archive padding during write use zero filled sections. This makes 1741556Srgrimes * it much easier to pull data out of flawed archive during read 1751556Srgrimes * operations. 1761556Srgrimes * 2.8 Access time reset with the -t applies to all file nodes (including 1771556Srgrimes * directories). 1781556Srgrimes * 2.9 Symbolic links can be followed with -L (optional in the spec). 1791556Srgrimes * 2.10 Modification or inode change time ranges can be specified via 1801556Srgrimes * multiple -T options. These allow a user to select files whose 1811556Srgrimes * modification or inode change time lies within a specific time range. 1821556Srgrimes * 2.11 Files can be selected based on owner (user name or uid) via one or more 1831556Srgrimes * -U options. 1841556Srgrimes * 2.12 Files can be selected based on group (group name or gid) via one o 1851556Srgrimes * more -G options. 1861556Srgrimes * 2.13 Symlinks which appear on the command line can be followed (without 1871556Srgrimes * following other symlinks; -H flag) 1881556Srgrimes * 1891556Srgrimes * 3 COPY ENHANCEMENTS 1901556Srgrimes * 3.1 Sparse files (lseek holes) can be copied without expanding the holes 1911556Srgrimes * into zero filled blocks. The file copy is created with holes which are 192102230Strhodes * appropriate for the target file system 1931556Srgrimes * 3.2 Access time as well as modification time on copied file trees can be 1941556Srgrimes * preserved with the appropriate -p options. 1951556Srgrimes * 3.3 Access time reset with the -t applies to all file nodes (including 1961556Srgrimes * directories). 1971556Srgrimes * 3.4 Symbolic links can be followed with -L (optional in the spec). 1981556Srgrimes * 3.5 Modification or inode change time ranges can be specified via 1991556Srgrimes * multiple -T options. These allow a user to select files whose 2001556Srgrimes * modification or inode change time lies within a specific time range. 2011556Srgrimes * 3.6 Files can be selected based on owner (user name or uid) via one or more 2021556Srgrimes * -U options. 2031556Srgrimes * 3.7 Files can be selected based on group (group name or gid) via one o 2041556Srgrimes * more -G options. 2051556Srgrimes * 3.8 Symlinks which appear on the command line can be followed (without 2061556Srgrimes * following other symlinks; -H flag) 20746684Skris * 3.9 File inode change time can be checked against existing file before 2081556Srgrimes * name modification (-D) 20946684Skris * 3.10 File inode change time can be checked against existing file after 2101556Srgrimes * name modification (-Y) 21146684Skris * 3.11 File modification time can be checked against existing file after 2121556Srgrimes * name modification (-Z) 2131556Srgrimes * 2141556Srgrimes * 4 GENERAL ENHANCEMENTS 2158855Srgrimes * 4.1 Internal structure is designed to isolate format dependent and 2161556Srgrimes * independent functions. Formats are selected via a format driver table. 2171556Srgrimes * This encourages the addition of new archive formats by only having to 2181556Srgrimes * write those routines which id, read and write the archive header. 2191556Srgrimes */ 2201556Srgrimes 2211556Srgrimes/* 2221556Srgrimes * main() 2231556Srgrimes * parse options, set up and operate as specified by the user. 2241556Srgrimes * any operational flaw will set exit_val to non-zero 2251556Srgrimes * Return: 0 if ok, 1 otherwise 2261556Srgrimes */ 2271556Srgrimes 2281556Srgrimesint 22990110Simpmain(int argc, char *argv[]) 2301556Srgrimes{ 231114583Smarkm const char *tmpdir; 23276016Skris size_t tdlen; 23376016Skris 23417517Sache (void) setlocale(LC_ALL, ""); 23581601Speter listf = stderr; 23676351Skris /* 23776351Skris * Keep a reference to cwd, so we can always come back home. 23876351Skris */ 23976351Skris cwdfd = open(".", O_RDONLY); 24076351Skris if (cwdfd < 0) { 24176351Skris syswarn(0, errno, "Can't open current working directory."); 24276351Skris return(exit_val); 24376351Skris } 24476016Skris 2451556Srgrimes /* 24676016Skris * Where should we put temporary files? 24776016Skris */ 24876016Skris if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') 24976016Skris tmpdir = _PATH_TMP; 25076016Skris tdlen = strlen(tmpdir); 25176016Skris while(tdlen > 0 && tmpdir[tdlen - 1] == '/') 25276016Skris tdlen--; 25376016Skris tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE)); 25476016Skris if (tempfile == NULL) { 25576017Skris paxwarn(1, "Cannot allocate memory for temp file name."); 25676016Skris return(exit_val); 25776016Skris } 25876016Skris if (tdlen) 25976016Skris memcpy(tempfile, tmpdir, tdlen); 26076016Skris tempbase = tempfile + tdlen; 26176016Skris *tempbase++ = '/'; 26276016Skris 26376016Skris /* 2641556Srgrimes * parse options, determine operational mode, general init 2651556Srgrimes */ 2661556Srgrimes options(argc, argv); 26776019Skris if ((gen_init() < 0) || (tty_init() < 0)) 2681556Srgrimes return(exit_val); 2691556Srgrimes 2701556Srgrimes /* 2718855Srgrimes * select a primary operation mode 2721556Srgrimes */ 2731556Srgrimes switch(act) { 2741556Srgrimes case EXTRACT: 2751556Srgrimes extract(); 2761556Srgrimes break; 2771556Srgrimes case ARCHIVE: 2781556Srgrimes archive(); 2791556Srgrimes break; 2801556Srgrimes case APPND: 28176286Skris if (gzip_program != NULL) 28276286Skris err(1, "can not gzip while appending"); 2831556Srgrimes append(); 2841556Srgrimes break; 2851556Srgrimes case COPY: 2861556Srgrimes copy(); 2871556Srgrimes break; 2881556Srgrimes default: 2891556Srgrimes case LIST: 2901556Srgrimes list(); 2911556Srgrimes break; 2921556Srgrimes } 2931556Srgrimes return(exit_val); 2941556Srgrimes} 2951556Srgrimes 2961556Srgrimes/* 2971556Srgrimes * sig_cleanup() 2981556Srgrimes * when interrupted we try to do whatever delayed processing we can. 2991556Srgrimes * This is not critical, but we really ought to limit our damage when we 3001556Srgrimes * are aborted by the user. 3011556Srgrimes * Return: 3021556Srgrimes * never.... 3031556Srgrimes */ 3041556Srgrimes 3051556Srgrimesvoid 3061556Srgrimessig_cleanup(int which_sig) 3071556Srgrimes{ 3081556Srgrimes /* 3091556Srgrimes * restore modes and times for any dirs we may have created 3101556Srgrimes * or any dirs we may have read. Set vflag and vfpart so the user 3111556Srgrimes * will clearly see the message on a line by itself. 3121556Srgrimes */ 3131556Srgrimes vflag = vfpart = 1; 3141556Srgrimes if (which_sig == SIGXCPU) 31576017Skris paxwarn(0, "Cpu time limit reached, cleaning up."); 3161556Srgrimes else 31776017Skris paxwarn(0, "Signal caught, cleaning up."); 3181556Srgrimes 3191556Srgrimes ar_close(); 3201556Srgrimes proc_dir(); 3211556Srgrimes if (tflag) 3221556Srgrimes atdir_end(); 3231556Srgrimes exit(1); 3241556Srgrimes} 3251556Srgrimes 3261556Srgrimes/* 3271556Srgrimes * gen_init() 3281556Srgrimes * general setup routines. Not all are required, but they really help 3291556Srgrimes * when dealing with a medium to large sized archives. 3301556Srgrimes */ 3311556Srgrimes 3321556Srgrimesstatic int 3331556Srgrimesgen_init(void) 3341556Srgrimes{ 3351556Srgrimes struct rlimit reslimit; 3361556Srgrimes struct sigaction n_hand; 3371556Srgrimes struct sigaction o_hand; 3381556Srgrimes 3391556Srgrimes /* 3401556Srgrimes * Really needed to handle large archives. We can run out of memory for 3411556Srgrimes * internal tables really fast when we have a whole lot of files... 3421556Srgrimes */ 3431556Srgrimes if (getrlimit(RLIMIT_DATA , &reslimit) == 0){ 3441556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3451556Srgrimes (void)setrlimit(RLIMIT_DATA , &reslimit); 3461556Srgrimes } 3471556Srgrimes 3481556Srgrimes /* 3491556Srgrimes * should file size limits be waived? if the os limits us, this is 3501556Srgrimes * needed if we want to write a large archive 3511556Srgrimes */ 3521556Srgrimes if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){ 3531556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3541556Srgrimes (void)setrlimit(RLIMIT_FSIZE , &reslimit); 3551556Srgrimes } 3561556Srgrimes 3571556Srgrimes /* 3581556Srgrimes * increase the size the stack can grow to 3591556Srgrimes */ 3601556Srgrimes if (getrlimit(RLIMIT_STACK , &reslimit) == 0){ 3611556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3621556Srgrimes (void)setrlimit(RLIMIT_STACK , &reslimit); 3631556Srgrimes } 3641556Srgrimes 3651556Srgrimes /* 3661556Srgrimes * not really needed, but doesn't hurt 3671556Srgrimes */ 3681556Srgrimes if (getrlimit(RLIMIT_RSS , &reslimit) == 0){ 3691556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3701556Srgrimes (void)setrlimit(RLIMIT_RSS , &reslimit); 3711556Srgrimes } 3721556Srgrimes 3731556Srgrimes /* 3741556Srgrimes * signal handling to reset stored directory times and modes. Since 3751556Srgrimes * we deal with broken pipes via failed writes we ignore it. We also 376222177Suqs * deal with any file size limit thorough failed writes. Cpu time 3771556Srgrimes * limits are caught and a cleanup is forced. 3781556Srgrimes */ 3791556Srgrimes if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) || 3801556Srgrimes (sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) || 3811556Srgrimes (sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0) || 3821556Srgrimes (sigaddset(&s_mask,SIGXCPU) < 0)||(sigaddset(&s_mask,SIGXFSZ)<0)) { 38376017Skris paxwarn(1, "Unable to set up signal mask"); 3841556Srgrimes return(-1); 3851556Srgrimes } 38676351Skris memset(&n_hand, 0, sizeof n_hand); 3871556Srgrimes n_hand.sa_mask = s_mask; 3881556Srgrimes n_hand.sa_flags = 0; 3891556Srgrimes n_hand.sa_handler = sig_cleanup; 3901556Srgrimes 3911556Srgrimes if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) && 3928855Srgrimes (o_hand.sa_handler == SIG_IGN) && 3931556Srgrimes (sigaction(SIGHUP, &o_hand, &o_hand) < 0)) 3941556Srgrimes goto out; 3951556Srgrimes 3961556Srgrimes if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) && 3978855Srgrimes (o_hand.sa_handler == SIG_IGN) && 3981556Srgrimes (sigaction(SIGTERM, &o_hand, &o_hand) < 0)) 3991556Srgrimes goto out; 4001556Srgrimes 4011556Srgrimes if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) && 4028855Srgrimes (o_hand.sa_handler == SIG_IGN) && 4031556Srgrimes (sigaction(SIGINT, &o_hand, &o_hand) < 0)) 4041556Srgrimes goto out; 4051556Srgrimes 4061556Srgrimes if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) && 4078855Srgrimes (o_hand.sa_handler == SIG_IGN) && 4081556Srgrimes (sigaction(SIGQUIT, &o_hand, &o_hand) < 0)) 4091556Srgrimes goto out; 4101556Srgrimes 4111556Srgrimes if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) && 4128855Srgrimes (o_hand.sa_handler == SIG_IGN) && 4131556Srgrimes (sigaction(SIGXCPU, &o_hand, &o_hand) < 0)) 4141556Srgrimes goto out; 4151556Srgrimes 4161556Srgrimes n_hand.sa_handler = SIG_IGN; 4171556Srgrimes if ((sigaction(SIGPIPE, &n_hand, &o_hand) < 0) || 4181556Srgrimes (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0)) 4191556Srgrimes goto out; 4201556Srgrimes return(0); 4211556Srgrimes 4221556Srgrimes out: 42376017Skris syswarn(1, errno, "Unable to set up signal handler"); 4241556Srgrimes return(-1); 4251556Srgrimes} 426