xref: /dragonfly/bin/pax/pax.c (revision eca362d0f9bd086cc56d6b5bc4f03f09e040b9db)
1 /*-
2  * Copyright (c) 1992 Keith Muller.
3  * Copyright (c) 1992, 1993
4  *        The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Keith Muller of the University of California, San Diego.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * @(#) Copyright (c) 1992, 1993 The Regents of the University of California.  All rights reserved.
34  * @(#)pax.c        8.2 (Berkeley) 4/18/94
35  * $FreeBSD: src/bin/pax/pax.c,v 1.13.2.4 2002/11/07 15:29:53 imp Exp $
36  */
37 
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <sys/time.h>
41 #include <sys/resource.h>
42 #include <err.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <locale.h>
46 #include <paths.h>
47 #include <signal.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52 #include "pax.h"
53 #include "extern.h"
54 static int gen_init(void);
55 
56 /*
57  * PAX main routines, general globals and some simple start up routines
58  */
59 
60 /*
61  * Variables that can be accessed by any routine within pax
62  */
63 int       act = DEFOP;                  /* read/write/append/copy */
64 FSUB      *frmt = NULL;                 /* archive format type */
65 int       cflag;                        /* match all EXCEPT pattern/file */
66 int       cwdfd;                        /* starting cwd */
67 int       dflag;                        /* directory member match only  */
68 int       iflag;                        /* interactive file/archive rename */
69 int       kflag;                        /* do not overwrite existing files */
70 int       lflag;                        /* use hard links when possible */
71 int       nflag;                        /* select first archive member match */
72 int       tflag;                        /* restore access time after read */
73 int       uflag;                        /* ignore older modification time files */
74 int       vflag;                        /* produce verbose output */
75 int       Dflag;                        /* same as uflag except inode change time */
76 int       Hflag;                        /* follow command line symlinks (write only) */
77 int       Lflag;                        /* follow symlinks when writing */
78 int       Xflag;                        /* archive files with same device id only */
79 int       Yflag;                        /* same as Dflag except after name mode */
80 int       Zflag;                        /* same as uflag except after name mode */
81 int       vfpart;                       /* is partial verbose output in progress */
82 int       patime = 1;                   /* preserve file access time */
83 int       pmtime = 1;                   /* preserve file modification times */
84 int       nodirs;                       /* do not create directories as needed */
85 int       pmode;                        /* preserve file mode bits */
86 int       pids;                         /* preserve file uid/gid */
87 int       rmleadslash = 0;    /* remove leading '/' from pathnames */
88 int       exit_val;           /* exit value */
89 int       docrc;                        /* check/create file crc */
90 char      *dirptr;            /* destination dir in a copy */
91 char      *argv0;                       /* root of argv[0] */
92 sigset_t s_mask;              /* signal mask for cleanup critical sect */
93 FILE      *listf;                       /* file pointer to print file list to */
94 char      *tempfile;                    /* tempfile to use for mkstemp(3) */
95 char      *tempbase;                    /* basename of tempfile to use for mkstemp(3) */
96 
97 /*
98  *        PAX - Portable Archive Interchange
99  *
100  *        A utility to read, write, and write lists of the members of archive
101  *        files and copy directory hierarchies. A variety of archive formats
102  *        are supported (some are described in POSIX 1003.1 10.1):
103  *
104  *                  ustar - 10.1.1 extended tar interchange format
105  *                  cpio  - 10.1.2 extended cpio interchange format
106  *                  tar - old BSD 4.3 tar format
107  *                  binary cpio - old cpio with binary header format
108  *                  sysVR4 cpio -  with and without CRC
109  *
110  * This version is a superset of IEEE Std 1003.2b-d3
111  *
112  * Summary of Extensions to the IEEE Standard:
113  *
114  * 1      READ ENHANCEMENTS
115  * 1.1    Operations which read archives will continue to operate even when
116  *        processing archives which may be damaged, truncated, or fail to meet
117  *        format specs in several different ways. Damaged sections of archives
118  *        are detected and avoided if possible. Attempts will be made to resync
119  *        archive read operations even with badly damaged media.
120  * 1.2    Blocksize requirements are not strictly enforced on archive read.
121  *        Tapes which have variable sized records can be read without errors.
122  * 1.3    The user can specify via the non-standard option flag -E if error
123  *        resync operation should stop on a media error, try a specified number
124  *        of times to correct, or try to correct forever.
125  * 1.4    Sparse files (lseek holes) stored on the archive (but stored with blocks
126  *        of all zeros will be restored with holes appropriate for the target
127  *        filesystem
128  * 1.5    The user is notified whenever something is found during archive
129  *        read operations which violates spec (but the read will continue).
130  * 1.6    Multiple archive volumes can be read and may span over different
131  *        archive devices
132  * 1.7    Rigidly restores all file attributes exactly as they are stored on the
133  *        archive.
134  * 1.8    Modification change time ranges can be specified via multiple -T
135  *        options. These allow a user to select files whose modification time
136  *        lies within a specific time range.
137  * 1.9    Files can be selected based on owner (user name or uid) via one or more
138  *        -U options.
139  * 1.10   Files can be selected based on group (group name or gid) via one o
140  *        more -G options.
141  * 1.11   File modification time can be checked against existing file after
142  *        name modification (-Z)
143  *
144  * 2      WRITE ENHANCEMENTS
145  * 2.1    Write operation will stop instead of allowing a user to create a flawed
146  *        flawed archive (due to any problem).
147  * 2.2    Archives written by pax are forced to strictly conform to both the
148  *        archive and pax the specific format specifications.
149  * 2.3    Blocking size and format is rigidly enforced on writes.
150  * 2.4    Formats which may exhibit header overflow problems (they have fields
151  *        too small for large file systems, such as inode number storage), use
152  *        routines designed to repair this problem. These techniques still
153  *        conform to both pax and format specifications, but no longer truncate
154  *        these fields. This removes any restrictions on using these archive
155  *        formats on large file systems.
156  * 2.5    Multiple archive volumes can be written and may span over different
157  *        archive devices
158  * 2.6    A archive volume record limit allows the user to specify the number
159  *        of bytes stored on an archive volume. When reached the user is
160  *        prompted for the next archive volume. This is specified with the
161  *        non-standard -B flag. The limit is rounded up to the next blocksize.
162  * 2.7    All archive padding during write use zero filled sections. This makes
163  *        it much easier to pull data out of flawed archive during read
164  *        operations.
165  * 2.8    Access time reset with the -t applies to all file nodes (including
166  *        directories).
167  * 2.9    Symbolic links can be followed with -L (optional in the spec).
168  * 2.10   Modification or inode change time ranges can be specified via
169  *        multiple -T options. These allow a user to select files whose
170  *        modification or inode change time lies within a specific time range.
171  * 2.11   Files can be selected based on owner (user name or uid) via one or more
172  *        -U options.
173  * 2.12   Files can be selected based on group (group name or gid) via one o
174  *        more -G options.
175  * 2.13   Symlinks which appear on the command line can be followed (without
176  *        following other symlinks; -H flag)
177  *
178  * 3      COPY ENHANCEMENTS
179  * 3.1    Sparse files (lseek holes) can be copied without expanding the holes
180  *        into zero filled blocks. The file copy is created with holes which are
181  *        appropriate for the target filesystem
182  * 3.2    Access time as well as modification time on copied file trees can be
183  *        preserved with the appropriate -p options.
184  * 3.3    Access time reset with the -t applies to all file nodes (including
185  *        directories).
186  * 3.4    Symbolic links can be followed with -L (optional in the spec).
187  * 3.5    Modification or inode change time ranges can be specified via
188  *        multiple -T options. These allow a user to select files whose
189  *        modification or inode change time lies within a specific time range.
190  * 3.6    Files can be selected based on owner (user name or uid) via one or more
191  *        -U options.
192  * 3.7    Files can be selected based on group (group name or gid) via one o
193  *        more -G options.
194  * 3.8    Symlinks which appear on the command line can be followed (without
195  *        following other symlinks; -H flag)
196  * 3.9  File inode change time can be checked against existing file before
197  *        name modification (-D)
198  * 3.10 File inode change time can be checked against existing file after
199  *        name modification (-Y)
200  * 3.11   File modification time can be checked against existing file after
201  *        name modification (-Z)
202  *
203  * 4      GENERAL ENHANCEMENTS
204  * 4.1    Internal structure is designed to isolate format dependent and
205  *        independent functions. Formats are selected via a format driver table.
206  *        This encourages the addition of new archive formats by only having to
207  *        write those routines which id, read and write the archive header.
208  */
209 
210 /*
211  * main()
212  *        parse options, set up and operate as specified by the user.
213  *        any operational flaw will set exit_val to non-zero
214  * Return: 0 if ok, 1 otherwise
215  */
216 
217 int
main(int argc,char * argv[])218 main(int argc, char *argv[])
219 {
220           const char *tmpdir;
221           size_t tdlen;
222 
223           setlocale(LC_ALL, "");
224           listf = stderr;
225           /*
226            * Keep a reference to cwd, so we can always come back home.
227            */
228           cwdfd = open(".", O_RDONLY | O_CLOEXEC);
229           if (cwdfd < 0) {
230                     syswarn(0, errno, "Can't open current working directory.");
231                     return(exit_val);
232           }
233 
234           /*
235            * Where should we put temporary files?
236            */
237           if ((tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0')
238                     tmpdir = _PATH_TMP;
239           tdlen = strlen(tmpdir);
240           while (tdlen > 0 && tmpdir[tdlen - 1] == '/')
241                     tdlen--;
242           tempfile = malloc(tdlen + 1 + sizeof(_TFILE_BASE));
243           if (tempfile == NULL) {
244                     paxwarn(1, "Cannot allocate memory for temp file name.");
245                     return(exit_val);
246           }
247           if (tdlen)
248                     memcpy(tempfile, tmpdir, tdlen);
249           tempbase = tempfile + tdlen;
250           *tempbase++ = '/';
251 
252           /*
253            * parse options, determine operational mode, general init
254            */
255           options(argc, argv);
256           if ((gen_init() < 0) || (tty_init() < 0))
257                     return(exit_val);
258 
259           /*
260            * select a primary operation mode
261            */
262           switch (act) {
263           case EXTRACT:
264                     extract();
265                     break;
266           case ARCHIVE:
267                     archive();
268                     break;
269           case APPND:
270                     if (gzip_program != NULL)
271                               err(1, "can not gzip while appending");
272                     append();
273                     break;
274           case COPY:
275                     copy();
276                     break;
277           default:
278           case LIST:
279                     list();
280                     break;
281           }
282           return(exit_val);
283 }
284 
285 /*
286  * sig_cleanup()
287  *        when interrupted we try to do whatever delayed processing we can.
288  *        This is not critical, but we really ought to limit our damage when we
289  *        are aborted by the user.
290  * Return:
291  *        never....
292  */
293 
294 void
sig_cleanup(int which_sig)295 sig_cleanup(int which_sig)
296 {
297           /*
298            * restore modes and times for any dirs we may have created
299            * or any dirs we may have read. Set vflag and vfpart so the user
300            * will clearly see the message on a line by itself.
301            */
302           vflag = vfpart = 1;
303           if (which_sig == SIGXCPU)
304                     paxwarn(0, "Cpu time limit reached, cleaning up.");
305           else
306                     paxwarn(0, "Signal caught, cleaning up.");
307 
308           ar_close();
309           proc_dir();
310           if (tflag)
311                     atdir_end();
312           exit(1);
313 }
314 
315 /*
316  * setup_sig()
317  *        set a signal to be caught, but only if it isn't being ignored already
318  */
319 
320 static int
setup_sig(int sig,const struct sigaction * n_hand)321 setup_sig(int sig, const struct sigaction *n_hand)
322 {
323           struct sigaction o_hand;
324 
325           if (sigaction(sig, NULL, &o_hand) < 0)
326                     return (-1);
327 
328           if (o_hand.sa_handler == SIG_IGN)
329                     return (0);
330 
331           return (sigaction(sig, n_hand, NULL));
332 }
333 
334 /*
335  * gen_init()
336  *        general setup routines. Not all are required, but they really help
337  *        when dealing with a medium to large sized archives.
338  */
339 
340 static int
gen_init(void)341 gen_init(void)
342 {
343           struct rlimit reslimit;
344           struct sigaction n_hand;
345 
346           /*
347            * Really needed to handle large archives. We can run out of memory for
348            * internal tables really fast when we have a whole lot of files...
349            */
350           if (getrlimit(RLIMIT_DATA , &reslimit) == 0){
351                     reslimit.rlim_cur = reslimit.rlim_max;
352                     setrlimit(RLIMIT_DATA , &reslimit);
353           }
354 
355           /*
356            * should file size limits be waived? if the os limits us, this is
357            * needed if we want to write a large archive
358            */
359           if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){
360                     reslimit.rlim_cur = reslimit.rlim_max;
361                     setrlimit(RLIMIT_FSIZE , &reslimit);
362           }
363 
364           /*
365            * increase the size the stack can grow to
366            */
367           if (getrlimit(RLIMIT_STACK , &reslimit) == 0){
368                     reslimit.rlim_cur = reslimit.rlim_max;
369                     setrlimit(RLIMIT_STACK , &reslimit);
370           }
371 
372           /*
373            * not really needed, but doesn't hurt
374            */
375           if (getrlimit(RLIMIT_RSS , &reslimit) == 0){
376                     reslimit.rlim_cur = reslimit.rlim_max;
377                     setrlimit(RLIMIT_RSS , &reslimit);
378           }
379 
380           /*
381            * signal handling to reset stored directory times and modes. Since
382            * we deal with broken pipes via failed writes we ignore it. We also
383            * deal with any file size limit through failed writes. Cpu time
384            * limits are caught and a cleanup is forced.
385            */
386           if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) ||
387               (sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) ||
388               (sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0) ||
389               (sigaddset(&s_mask,SIGXCPU) < 0)||(sigaddset(&s_mask,SIGXFSZ)<0)) {
390                     paxwarn(1, "Unable to set up signal mask");
391                     return(-1);
392           }
393           memset(&n_hand, 0, sizeof n_hand);
394           n_hand.sa_mask = s_mask;
395           n_hand.sa_flags = 0;
396           n_hand.sa_handler = sig_cleanup;
397 
398           if (setup_sig(SIGHUP,  &n_hand) ||
399               setup_sig(SIGTERM, &n_hand) ||
400               setup_sig(SIGINT,  &n_hand) ||
401               setup_sig(SIGQUIT, &n_hand) ||
402               setup_sig(SIGXCPU, &n_hand))
403                     goto out;
404 
405           n_hand.sa_handler = SIG_IGN;
406           if ((sigaction(SIGPIPE, &n_hand, NULL) < 0) ||
407               (sigaction(SIGXFSZ, &n_hand, NULL) < 0))
408                     goto out;
409           return(0);
410 
411     out:
412           syswarn(1, errno, "Unable to set up signal handler");
413           return(-1);
414 }
415