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$"); 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 "pax.h" 621556Srgrimes#include "extern.h" 6390110Simpstatic int gen_init(void); 641556Srgrimes 651556Srgrimes/* 661556Srgrimes * PAX main routines, general globals and some simple start up routines 671556Srgrimes */ 681556Srgrimes 691556Srgrimes/* 701556Srgrimes * Variables that can be accessed by any routine within pax 711556Srgrimes */ 721556Srgrimesint act = DEFOP; /* read/write/append/copy */ 731556SrgrimesFSUB *frmt = NULL; /* archive format type */ 741556Srgrimesint cflag; /* match all EXCEPT pattern/file */ 7576351Skrisint cwdfd; /* starting cwd */ 761556Srgrimesint dflag; /* directory member match only */ 771556Srgrimesint iflag; /* interactive file/archive rename */ 781556Srgrimesint kflag; /* do not overwrite existing files */ 791556Srgrimesint lflag; /* use hard links when possible */ 801556Srgrimesint nflag; /* select first archive member match */ 811556Srgrimesint tflag; /* restore access time after read */ 821556Srgrimesint uflag; /* ignore older modification time files */ 831556Srgrimesint vflag; /* produce verbose output */ 841556Srgrimesint Dflag; /* same as uflag except inode change time */ 851556Srgrimesint Hflag; /* follow command line symlinks (write only) */ 861556Srgrimesint Lflag; /* follow symlinks when writing */ 87281661Seadlerint Oflag; /* limit to single volume */ 881556Srgrimesint Xflag; /* archive files with same device id only */ 891556Srgrimesint Yflag; /* same as Dflg except after name mode */ 901556Srgrimesint Zflag; /* same as uflg except after name mode */ 911556Srgrimesint vfpart; /* is partial verbose output in progress */ 921556Srgrimesint patime = 1; /* preserve file access time */ 931556Srgrimesint pmtime = 1; /* preserve file modification times */ 9476351Skrisint nodirs; /* do not create directories as needed */ 951556Srgrimesint pmode; /* preserve file mode bits */ 961556Srgrimesint pids; /* preserve file uid/gid */ 9776351Skrisint rmleadslash = 0; /* remove leading '/' from pathnames */ 981556Srgrimesint exit_val; /* exit value */ 991556Srgrimesint docrc; /* check/create file crc */ 1001556Srgrimeschar *dirptr; /* destination dir in a copy */ 101114583Smarkmconst char *argv0; /* root of argv[0] */ 10276351Skrissigset_t s_mask; /* signal mask for cleanup critical sect */ 10381601SpeterFILE *listf; /* file pointer to print file list to */ 10476016Skrischar *tempfile; /* tempfile to use for mkstemp(3) */ 10576016Skrischar *tempbase; /* basename of tempfile to use for mkstemp(3) */ 1061556Srgrimes 1071556Srgrimes/* 1081556Srgrimes * PAX - Portable Archive Interchange 1091556Srgrimes * 1101556Srgrimes * A utility to read, write, and write lists of the members of archive 1111556Srgrimes * files and copy directory hierarchies. A variety of archive formats 1121556Srgrimes * are supported (some are described in POSIX 1003.1 10.1): 1131556Srgrimes * 1141556Srgrimes * ustar - 10.1.1 extended tar interchange format 1151556Srgrimes * cpio - 10.1.2 extended cpio interchange format 1161556Srgrimes * tar - old BSD 4.3 tar format 1171556Srgrimes * binary cpio - old cpio with binary header format 1181556Srgrimes * sysVR4 cpio - with and without CRC 1191556Srgrimes * 1201556Srgrimes * This version is a superset of IEEE Std 1003.2b-d3 1211556Srgrimes * 1221556Srgrimes * Summary of Extensions to the IEEE Standard: 1231556Srgrimes * 1241556Srgrimes * 1 READ ENHANCEMENTS 1251556Srgrimes * 1.1 Operations which read archives will continue to operate even when 1268855Srgrimes * processing archives which may be damaged, truncated, or fail to meet 1271556Srgrimes * format specs in several different ways. Damaged sections of archives 1281556Srgrimes * are detected and avoided if possible. Attempts will be made to resync 1291556Srgrimes * archive read operations even with badly damaged media. 1301556Srgrimes * 1.2 Blocksize requirements are not strictly enforced on archive read. 1311556Srgrimes * Tapes which have variable sized records can be read without errors. 1321556Srgrimes * 1.3 The user can specify via the non-standard option flag -E if error 1331556Srgrimes * resync operation should stop on a media error, try a specified number 1341556Srgrimes * of times to correct, or try to correct forever. 1351556Srgrimes * 1.4 Sparse files (lseek holes) stored on the archive (but stored with blocks 1361556Srgrimes * of all zeros will be restored with holes appropriate for the target 137102230Strhodes * file system 1381556Srgrimes * 1.5 The user is notified whenever something is found during archive 1391556Srgrimes * read operations which violates spec (but the read will continue). 1401556Srgrimes * 1.6 Multiple archive volumes can be read and may span over different 1418855Srgrimes * archive devices 1421556Srgrimes * 1.7 Rigidly restores all file attributes exactly as they are stored on the 1431556Srgrimes * archive. 1441556Srgrimes * 1.8 Modification change time ranges can be specified via multiple -T 1451556Srgrimes * options. These allow a user to select files whose modification time 1461556Srgrimes * lies within a specific time range. 1471556Srgrimes * 1.9 Files can be selected based on owner (user name or uid) via one or more 1481556Srgrimes * -U options. 1491556Srgrimes * 1.10 Files can be selected based on group (group name or gid) via one o 1501556Srgrimes * more -G options. 15146684Skris * 1.11 File modification time can be checked against existing file after 1521556Srgrimes * name modification (-Z) 1531556Srgrimes * 1541556Srgrimes * 2 WRITE ENHANCEMENTS 1551556Srgrimes * 2.1 Write operation will stop instead of allowing a user to create a flawed 1561556Srgrimes * flawed archive (due to any problem). 15746684Skris * 2.2 Archives written by pax are forced to strictly conform to both the 15846684Skris * archive and pax the specific format specifications. 1591556Srgrimes * 2.3 Blocking size and format is rigidly enforced on writes. 1601556Srgrimes * 2.4 Formats which may exhibit header overflow problems (they have fields 161102230Strhodes * too small for large file systems, such as inode number storage), use 1621556Srgrimes * routines designed to repair this problem. These techniques still 1631556Srgrimes * conform to both pax and format specifications, but no longer truncate 1641556Srgrimes * these fields. This removes any restrictions on using these archive 165102230Strhodes * formats on large file systems. 1661556Srgrimes * 2.5 Multiple archive volumes can be written and may span over different 1678855Srgrimes * archive devices 1681556Srgrimes * 2.6 A archive volume record limit allows the user to specify the number 1691556Srgrimes * of bytes stored on an archive volume. When reached the user is 1701556Srgrimes * prompted for the next archive volume. This is specified with the 17146684Skris * non-standard -B flag. The limit is rounded up to the next blocksize. 1721556Srgrimes * 2.7 All archive padding during write use zero filled sections. This makes 1731556Srgrimes * it much easier to pull data out of flawed archive during read 1741556Srgrimes * operations. 1751556Srgrimes * 2.8 Access time reset with the -t applies to all file nodes (including 1761556Srgrimes * directories). 1771556Srgrimes * 2.9 Symbolic links can be followed with -L (optional in the spec). 1781556Srgrimes * 2.10 Modification or inode change time ranges can be specified via 1791556Srgrimes * multiple -T options. These allow a user to select files whose 1801556Srgrimes * modification or inode change time lies within a specific time range. 1811556Srgrimes * 2.11 Files can be selected based on owner (user name or uid) via one or more 1821556Srgrimes * -U options. 1831556Srgrimes * 2.12 Files can be selected based on group (group name or gid) via one o 1841556Srgrimes * more -G options. 1851556Srgrimes * 2.13 Symlinks which appear on the command line can be followed (without 1861556Srgrimes * following other symlinks; -H flag) 1871556Srgrimes * 1881556Srgrimes * 3 COPY ENHANCEMENTS 1891556Srgrimes * 3.1 Sparse files (lseek holes) can be copied without expanding the holes 1901556Srgrimes * into zero filled blocks. The file copy is created with holes which are 191102230Strhodes * appropriate for the target file system 1921556Srgrimes * 3.2 Access time as well as modification time on copied file trees can be 1931556Srgrimes * preserved with the appropriate -p options. 1941556Srgrimes * 3.3 Access time reset with the -t applies to all file nodes (including 1951556Srgrimes * directories). 1961556Srgrimes * 3.4 Symbolic links can be followed with -L (optional in the spec). 1971556Srgrimes * 3.5 Modification or inode change time ranges can be specified via 1981556Srgrimes * multiple -T options. These allow a user to select files whose 1991556Srgrimes * modification or inode change time lies within a specific time range. 2001556Srgrimes * 3.6 Files can be selected based on owner (user name or uid) via one or more 2011556Srgrimes * -U options. 2021556Srgrimes * 3.7 Files can be selected based on group (group name or gid) via one o 2031556Srgrimes * more -G options. 2041556Srgrimes * 3.8 Symlinks which appear on the command line can be followed (without 2051556Srgrimes * following other symlinks; -H flag) 20646684Skris * 3.9 File inode change time can be checked against existing file before 2071556Srgrimes * name modification (-D) 20846684Skris * 3.10 File inode change time can be checked against existing file after 2091556Srgrimes * name modification (-Y) 21046684Skris * 3.11 File modification time can be checked against existing file after 2111556Srgrimes * name modification (-Z) 2121556Srgrimes * 2131556Srgrimes * 4 GENERAL ENHANCEMENTS 2148855Srgrimes * 4.1 Internal structure is designed to isolate format dependent and 2151556Srgrimes * independent functions. Formats are selected via a format driver table. 2161556Srgrimes * This encourages the addition of new archive formats by only having to 2171556Srgrimes * write those routines which id, read and write the archive header. 2181556Srgrimes */ 2191556Srgrimes 2201556Srgrimes/* 2211556Srgrimes * main() 2221556Srgrimes * parse options, set up and operate as specified by the user. 2231556Srgrimes * any operational flaw will set exit_val to non-zero 2241556Srgrimes * Return: 0 if ok, 1 otherwise 2251556Srgrimes */ 2261556Srgrimes 2271556Srgrimesint 22890110Simpmain(int argc, char *argv[]) 2291556Srgrimes{ 230114583Smarkm const char *tmpdir; 23176016Skris size_t tdlen; 23276016Skris 23317517Sache (void) setlocale(LC_ALL, ""); 23481601Speter listf = stderr; 23576351Skris /* 23676351Skris * Keep a reference to cwd, so we can always come back home. 23776351Skris */ 23876351Skris cwdfd = open(".", O_RDONLY); 23976351Skris if (cwdfd < 0) { 24076351Skris syswarn(0, errno, "Can't open current working directory."); 24176351Skris return(exit_val); 24276351Skris } 24376016Skris 2441556Srgrimes /* 24576016Skris * Where should we put temporary files? 24676016Skris */ 24776016Skris if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') 24876016Skris tmpdir = _PATH_TMP; 24976016Skris tdlen = strlen(tmpdir); 25076016Skris while(tdlen > 0 && tmpdir[tdlen - 1] == '/') 25176016Skris tdlen--; 25276016Skris tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE)); 25376016Skris if (tempfile == NULL) { 25476017Skris paxwarn(1, "Cannot allocate memory for temp file name."); 25576016Skris return(exit_val); 25676016Skris } 25776016Skris if (tdlen) 25876016Skris memcpy(tempfile, tmpdir, tdlen); 25976016Skris tempbase = tempfile + tdlen; 26076016Skris *tempbase++ = '/'; 26176016Skris 26276016Skris /* 2631556Srgrimes * parse options, determine operational mode, general init 2641556Srgrimes */ 2651556Srgrimes options(argc, argv); 26676019Skris if ((gen_init() < 0) || (tty_init() < 0)) 2671556Srgrimes return(exit_val); 2681556Srgrimes 2691556Srgrimes /* 2708855Srgrimes * select a primary operation mode 2711556Srgrimes */ 2721556Srgrimes switch(act) { 2731556Srgrimes case EXTRACT: 2741556Srgrimes extract(); 2751556Srgrimes break; 2761556Srgrimes case ARCHIVE: 2771556Srgrimes archive(); 2781556Srgrimes break; 2791556Srgrimes case APPND: 28076286Skris if (gzip_program != NULL) 28176286Skris err(1, "can not gzip while appending"); 2821556Srgrimes append(); 2831556Srgrimes break; 2841556Srgrimes case COPY: 2851556Srgrimes copy(); 2861556Srgrimes break; 2871556Srgrimes default: 2881556Srgrimes case LIST: 2891556Srgrimes list(); 2901556Srgrimes break; 2911556Srgrimes } 2921556Srgrimes return(exit_val); 2931556Srgrimes} 2941556Srgrimes 2951556Srgrimes/* 2961556Srgrimes * sig_cleanup() 2971556Srgrimes * when interrupted we try to do whatever delayed processing we can. 2981556Srgrimes * This is not critical, but we really ought to limit our damage when we 2991556Srgrimes * are aborted by the user. 3001556Srgrimes * Return: 3011556Srgrimes * never.... 3021556Srgrimes */ 3031556Srgrimes 3041556Srgrimesvoid 3051556Srgrimessig_cleanup(int which_sig) 3061556Srgrimes{ 3071556Srgrimes /* 3081556Srgrimes * restore modes and times for any dirs we may have created 3091556Srgrimes * or any dirs we may have read. Set vflag and vfpart so the user 3101556Srgrimes * will clearly see the message on a line by itself. 3111556Srgrimes */ 3121556Srgrimes vflag = vfpart = 1; 3131556Srgrimes if (which_sig == SIGXCPU) 31476017Skris paxwarn(0, "Cpu time limit reached, cleaning up."); 3151556Srgrimes else 31676017Skris paxwarn(0, "Signal caught, cleaning up."); 3171556Srgrimes 3181556Srgrimes ar_close(); 3191556Srgrimes proc_dir(); 3201556Srgrimes if (tflag) 3211556Srgrimes atdir_end(); 3221556Srgrimes exit(1); 3231556Srgrimes} 3241556Srgrimes 3251556Srgrimes/* 3261556Srgrimes * gen_init() 3271556Srgrimes * general setup routines. Not all are required, but they really help 3281556Srgrimes * when dealing with a medium to large sized archives. 3291556Srgrimes */ 3301556Srgrimes 3311556Srgrimesstatic int 3321556Srgrimesgen_init(void) 3331556Srgrimes{ 3341556Srgrimes struct rlimit reslimit; 3351556Srgrimes struct sigaction n_hand; 3361556Srgrimes struct sigaction o_hand; 3371556Srgrimes 3381556Srgrimes /* 3391556Srgrimes * Really needed to handle large archives. We can run out of memory for 3401556Srgrimes * internal tables really fast when we have a whole lot of files... 3411556Srgrimes */ 3421556Srgrimes if (getrlimit(RLIMIT_DATA , &reslimit) == 0){ 3431556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3441556Srgrimes (void)setrlimit(RLIMIT_DATA , &reslimit); 3451556Srgrimes } 3461556Srgrimes 3471556Srgrimes /* 3481556Srgrimes * should file size limits be waived? if the os limits us, this is 3491556Srgrimes * needed if we want to write a large archive 3501556Srgrimes */ 3511556Srgrimes if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){ 3521556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3531556Srgrimes (void)setrlimit(RLIMIT_FSIZE , &reslimit); 3541556Srgrimes } 3551556Srgrimes 3561556Srgrimes /* 3571556Srgrimes * increase the size the stack can grow to 3581556Srgrimes */ 3591556Srgrimes if (getrlimit(RLIMIT_STACK , &reslimit) == 0){ 3601556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3611556Srgrimes (void)setrlimit(RLIMIT_STACK , &reslimit); 3621556Srgrimes } 3631556Srgrimes 3641556Srgrimes /* 3651556Srgrimes * not really needed, but doesn't hurt 3661556Srgrimes */ 3671556Srgrimes if (getrlimit(RLIMIT_RSS , &reslimit) == 0){ 3681556Srgrimes reslimit.rlim_cur = reslimit.rlim_max; 3691556Srgrimes (void)setrlimit(RLIMIT_RSS , &reslimit); 3701556Srgrimes } 3711556Srgrimes 3721556Srgrimes /* 3731556Srgrimes * signal handling to reset stored directory times and modes. Since 3741556Srgrimes * we deal with broken pipes via failed writes we ignore it. We also 375222177Suqs * deal with any file size limit thorough failed writes. Cpu time 3761556Srgrimes * limits are caught and a cleanup is forced. 3771556Srgrimes */ 3781556Srgrimes if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) || 3791556Srgrimes (sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) || 3801556Srgrimes (sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0) || 3811556Srgrimes (sigaddset(&s_mask,SIGXCPU) < 0)||(sigaddset(&s_mask,SIGXFSZ)<0)) { 38276017Skris paxwarn(1, "Unable to set up signal mask"); 3831556Srgrimes return(-1); 3841556Srgrimes } 38576351Skris memset(&n_hand, 0, sizeof n_hand); 3861556Srgrimes n_hand.sa_mask = s_mask; 3871556Srgrimes n_hand.sa_flags = 0; 3881556Srgrimes n_hand.sa_handler = sig_cleanup; 3891556Srgrimes 3901556Srgrimes if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) && 3918855Srgrimes (o_hand.sa_handler == SIG_IGN) && 3921556Srgrimes (sigaction(SIGHUP, &o_hand, &o_hand) < 0)) 3931556Srgrimes goto out; 3941556Srgrimes 3951556Srgrimes if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) && 3968855Srgrimes (o_hand.sa_handler == SIG_IGN) && 3971556Srgrimes (sigaction(SIGTERM, &o_hand, &o_hand) < 0)) 3981556Srgrimes goto out; 3991556Srgrimes 4001556Srgrimes if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) && 4018855Srgrimes (o_hand.sa_handler == SIG_IGN) && 4021556Srgrimes (sigaction(SIGINT, &o_hand, &o_hand) < 0)) 4031556Srgrimes goto out; 4041556Srgrimes 4051556Srgrimes if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) && 4068855Srgrimes (o_hand.sa_handler == SIG_IGN) && 4071556Srgrimes (sigaction(SIGQUIT, &o_hand, &o_hand) < 0)) 4081556Srgrimes goto out; 4091556Srgrimes 4101556Srgrimes if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) && 4118855Srgrimes (o_hand.sa_handler == SIG_IGN) && 4121556Srgrimes (sigaction(SIGXCPU, &o_hand, &o_hand) < 0)) 4131556Srgrimes goto out; 4141556Srgrimes 4151556Srgrimes n_hand.sa_handler = SIG_IGN; 4161556Srgrimes if ((sigaction(SIGPIPE, &n_hand, &o_hand) < 0) || 4171556Srgrimes (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0)) 4181556Srgrimes goto out; 4191556Srgrimes return(0); 4201556Srgrimes 4211556Srgrimes out: 42276017Skris syswarn(1, errno, "Unable to set up signal handler"); 4231556Srgrimes return(-1); 4241556Srgrimes} 425