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