Imported Debian patch 1.5-16
[debian/pax] / pax.c
1 /*      $OpenBSD: pax.c,v 1.14 1998/09/20 02:22:22 millert 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. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *      This product includes software developed by the University of
23  *      California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  */
40
41 #ifndef lint
42 static char copyright[] =
43 "@(#) Copyright (c) 1992, 1993\n\
44         The Regents of the University of California.  All rights reserved.\n";
45 #endif /* not lint */
46
47 #ifndef lint
48 #if 0
49 static char sccsid[] = "@(#)pax.c       8.2 (Berkeley) 4/18/94";
50 #else
51 static char rcsid[] = "$OpenBSD: pax.c,v 1.14 1998/09/20 02:22:22 millert Exp $";
52 #endif
53 #endif /* not lint */
54
55 #include <stdio.h>
56 #include <sys/types.h>
57 #include <sys/param.h>
58 #include <sys/stat.h>
59 #include <sys/time.h>
60 #include <sys/resource.h>
61 #include <signal.h>
62 #include <unistd.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <errno.h>
66 #include <fcntl.h>
67 #include "pax.h"
68 #include "extern.h"
69 static int gen_init __P((void));
70
71 /*
72  * PAX main routines, general globals and some simple start up routines
73  */
74
75 /*
76  * Variables that can be accessed by any routine within pax
77  */
78 int     act = DEFOP;            /* read/write/append/copy */
79 FSUB    *frmt = NULL;           /* archive format type */
80 int     cflag;                  /* match all EXCEPT pattern/file */
81 int     cwdfd;                  /* starting cwd */
82 int     dflag;                  /* directory member match only  */
83 int     iflag;                  /* interactive file/archive rename */
84 int     kflag;                  /* do not overwrite existing files */
85 int     lflag;                  /* use hard links when possible */
86 int     nflag;                  /* select first archive member match */
87 int     tflag;                  /* restore access time after read */
88 int     uflag;                  /* ignore older modification time files */
89 int     vflag;                  /* produce verbose output */
90 int     zflag;                  /* use compress, gzip or bzip2 */
91 int     Dflag;                  /* same as uflag except inode change time */
92 int     Hflag;                  /* follow command line symlinks (write only) */
93 int     Lflag;                  /* follow symlinks when writing */
94 int     Xflag;                  /* archive files with same device id only */
95 int     Yflag;                  /* same as Dflg except after name mode */
96 int     Zflag;                  /* same as uflg except after name mode */
97 int     vfpart;                 /* is partial verbose output in progress */
98 int     patime = 1;             /* preserve file access time */
99 int     pmtime = 1;             /* preserve file modification times */
100 int     nodirs;                 /* do not create directories as needed */
101 int     pmode;                  /* preserve file mode bits */
102 int     pids;                   /* preserve file uid/gid */
103 int     rmleadslash = 0;        /* remove leading '/' from pathnames */
104 int     exit_val;               /* exit value */
105 int     docrc;                  /* check/create file crc */
106 char    *dirptr;                /* destination dir in a copy */
107 char    *ltmfrmt;               /* -v locale time format (if any) */
108 char    *argv0;                 /* root of argv[0] */
109 sigset_t s_mask;                /* signal mask for cleanup critical sect */
110 FILE    *listf;                 /* file pointer to print file list to */
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 exisiting 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 writtens by pax are forced to strictly conform to both the
163  *      archive and pax the spceific 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 exisiting file before
212  *      name modification (-D)
213  * 3.10 File inode change time can be checked against exisiting file after
214  *      name modification (-Y)
215  * 3.11 File modification time can be checked against exisiting 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 #ifdef __STDC__
233 int
234 main(int argc, char **argv)
235 #else
236 int
237 main(argc, argv)
238         int argc;
239         char **argv;
240 #endif
241 {
242         listf = stderr;
243
244         /*
245          * Keep a reference to cwd, so we can always come back home.
246          */
247         cwdfd = open(".", O_RDONLY);
248         if (cwdfd < 0) {
249                 syswarn(0, errno, "Can't open current working directory.");
250                 return(exit_val);
251         }
252
253         /*
254          * parse options, determine operational mode, general init
255          */
256         options(argc, argv);
257         if ((gen_init() < 0) || (tty_init() < 0))
258                 return(exit_val);
259
260         /*
261          * select a primary operation mode 
262          */
263         switch(act) {
264         case EXTRACT:
265                 extract();
266                 break;
267         case ARCHIVE:
268                 archive();
269                 break;
270         case APPND:
271                 append();
272                 break;
273         case COPY:
274                 copy();
275                 break;
276         default:
277         case LIST:
278                 list();
279                 break;
280         }
281         return(exit_val);
282 }
283
284 /*
285  * sig_cleanup()
286  *      when interrupted we try to do whatever delayed processing we can.
287  *      This is not critical, but we really ought to limit our damage when we
288  *      are aborted by the user.
289  * Return:
290  *      never....
291  */
292
293 #ifdef __STDC__
294 void
295 sig_cleanup(int which_sig)
296 #else
297 void
298 sig_cleanup(which_sig)
299         int which_sig;
300 #endif
301 {
302         /*
303          * restore modes and times for any dirs we may have created
304          * or any dirs we may have read. Set vflag and vfpart so the user
305          * will clearly see the message on a line by itself.
306          */
307         vflag = vfpart = 1;
308         if (which_sig == SIGXCPU)
309                 paxwarn(0, "Cpu time limit reached, cleaning up.");
310         else
311                 paxwarn(0, "Signal caught, cleaning up.");
312
313         ar_close();
314         proc_dir();
315         if (tflag)
316                 atdir_end();
317         exit(1);
318 }
319
320 /*
321  * gen_init()
322  *      general setup routines. Not all are required, but they really help
323  *      when dealing with a medium to large sized archives.
324  */
325
326 #ifdef __STDC__
327 static int
328 gen_init(void)
329 #else
330 static int
331 gen_init()
332 #endif
333 {
334         struct rlimit reslimit;
335         struct sigaction n_hand;
336         struct sigaction o_hand;
337
338         /*
339          * Really needed to handle large archives. We can run out of memory for
340          * internal tables really fast when we have a whole lot of files...
341          */
342         if (getrlimit(RLIMIT_DATA , &reslimit) == 0){
343                 reslimit.rlim_cur = reslimit.rlim_max;
344                 (void)setrlimit(RLIMIT_DATA , &reslimit);
345         }
346
347         /*
348          * should file size limits be waived? if the os limits us, this is
349          * needed if we want to write a large archive
350          */
351         if (getrlimit(RLIMIT_FSIZE , &reslimit) == 0){
352                 reslimit.rlim_cur = reslimit.rlim_max;
353                 (void)setrlimit(RLIMIT_FSIZE , &reslimit);
354         }
355
356         /*
357          * increase the size the stack can grow to
358          */
359         if (getrlimit(RLIMIT_STACK , &reslimit) == 0){
360                 reslimit.rlim_cur = reslimit.rlim_max;
361                 (void)setrlimit(RLIMIT_STACK , &reslimit);
362         }
363
364         /*
365          * not really needed, but doesn't hurt
366          */
367         if (getrlimit(RLIMIT_RSS , &reslimit) == 0){
368                 reslimit.rlim_cur = reslimit.rlim_max;
369                 (void)setrlimit(RLIMIT_RSS , &reslimit);
370         }
371
372         /*
373          * Handle posix locale
374          *
375          * set user defines time printing format for -v option 
376          */
377         ltmfrmt = getenv("LC_TIME");
378
379         /*
380          * signal handling to reset stored directory times and modes. Since
381          * we deal with broken pipes via failed writes we ignore it. We also
382          * deal with any file size limit thorugh failed writes. Cpu time
383          * limits are caught and a cleanup is forced.
384          */
385         if ((sigemptyset(&s_mask) < 0) || (sigaddset(&s_mask, SIGTERM) < 0) ||
386             (sigaddset(&s_mask,SIGINT) < 0)||(sigaddset(&s_mask,SIGHUP) < 0) ||
387             (sigaddset(&s_mask,SIGPIPE) < 0)||(sigaddset(&s_mask,SIGQUIT)<0) ||
388             (sigaddset(&s_mask,SIGXCPU) < 0)||(sigaddset(&s_mask,SIGXFSZ)<0)) {
389                 paxwarn(1, "Unable to set up signal mask");
390                 return(-1);
391         }
392         memset(&n_hand, 0, sizeof n_hand);
393         n_hand.sa_mask = s_mask;
394         n_hand.sa_flags = 0;
395         n_hand.sa_handler = sig_cleanup;
396
397         if ((sigaction(SIGHUP, &n_hand, &o_hand) < 0) &&
398             (o_hand.sa_handler == SIG_IGN) &&
399             (sigaction(SIGHUP, &o_hand, &o_hand) < 0))
400                 goto out;
401
402         if ((sigaction(SIGTERM, &n_hand, &o_hand) < 0) &&
403             (o_hand.sa_handler == SIG_IGN) &&
404             (sigaction(SIGTERM, &o_hand, &o_hand) < 0))
405                 goto out;
406
407         if ((sigaction(SIGINT, &n_hand, &o_hand) < 0) &&
408             (o_hand.sa_handler == SIG_IGN) &&
409             (sigaction(SIGINT, &o_hand, &o_hand) < 0))
410                 goto out;
411
412         if ((sigaction(SIGQUIT, &n_hand, &o_hand) < 0) &&
413             (o_hand.sa_handler == SIG_IGN) &&
414             (sigaction(SIGQUIT, &o_hand, &o_hand) < 0))
415                 goto out;
416
417         if ((sigaction(SIGXCPU, &n_hand, &o_hand) < 0) &&
418             (o_hand.sa_handler == SIG_IGN) &&
419             (sigaction(SIGXCPU, &o_hand, &o_hand) < 0))
420                 goto out;
421
422         n_hand.sa_handler = SIG_IGN;
423         if ((sigaction(SIGPIPE, &n_hand, &o_hand) < 0) ||
424             (sigaction(SIGXFSZ, &n_hand, &o_hand) < 0))
425                 goto out;
426         return(0);
427
428     out:
429         syswarn(1, errno, "Unable to set up signal handler");
430         return(-1);
431 }