Initial import from FreeBSD RELENG_4:
[dragonfly.git] / bin / pax / ar_subs.c
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. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)ar_subs.c   8.2 (Berkeley) 4/18/94";
41 #endif
42 static const char rcsid[] =
43   "$FreeBSD: src/bin/pax/ar_subs.c,v 1.13.2.1 2001/08/01 05:03:11 obrien Exp $";
44 #endif /* not lint */
45
46 #include <sys/types.h>
47 #include <sys/time.h>
48 #include <sys/stat.h>
49 #include <signal.h>
50 #include <string.h>
51 #include <stdio.h>
52 #include <fcntl.h>
53 #include <errno.h>
54 #include <unistd.h>
55 #include <stdlib.h>
56 #include "pax.h"
57 #include "extern.h"
58
59 static void wr_archive __P((register ARCHD *, int is_app));
60 static int get_arc __P((void));
61 static int next_head __P((register ARCHD *));
62 extern sigset_t s_mask;
63
64 /*
65  * Routines which control the overall operation modes of pax as specified by
66  * the user: list, append, read ...
67  */
68
69 static char hdbuf[BLKMULT];             /* space for archive header on read */
70 u_long flcnt;                           /* number of files processed */
71
72 /*
73  * list()
74  *      list the contents of an archive which match user supplied pattern(s)
75  *      (no pattern matches all).
76  */
77
78 #ifdef __STDC__
79 void
80 list(void)
81 #else
82 void
83 list()
84 #endif
85 {
86         register ARCHD *arcn;
87         register int res;
88         ARCHD archd;
89         time_t now;
90
91         arcn = &archd;
92         /*
93          * figure out archive type; pass any format specific options to the
94          * archive option processing routine; call the format init routine. We
95          * also save current time for ls_list() so we do not make a system
96          * call for each file we need to print. If verbose (vflag) start up
97          * the name and group caches.
98          */
99         if ((get_arc() < 0) || ((*frmt->options)() < 0) ||
100             ((*frmt->st_rd)() < 0))
101                 return;
102
103         if (vflag && ((uidtb_start() < 0) || (gidtb_start() < 0)))
104                 return;
105
106         now = time(NULL);
107
108         /*
109          * step through the archive until the format says it is done
110          */
111         while (next_head(arcn) == 0) {
112                 /*
113                  * check for pattern, and user specified options match.
114                  * When all patterns are matched we are done.
115                  */
116                 if ((res = pat_match(arcn)) < 0)
117                         break;
118
119                 if ((res == 0) && (sel_chk(arcn) == 0)) {
120                         /*
121                          * pattern resulted in a selected file
122                          */
123                         if (pat_sel(arcn) < 0)
124                                 break;
125
126                         /*
127                          * modify the name as requested by the user if name
128                          * survives modification, do a listing of the file
129                          */
130                         if ((res = mod_name(arcn)) < 0)
131                                 break;
132                         if (res == 0)
133                                 ls_list(arcn, now, stdout);
134                 }
135
136                 /*
137                  * skip to next archive format header using values calculated
138                  * by the format header read routine
139                  */
140                 if (rd_skip(arcn->skip + arcn->pad) == 1)
141                         break;
142         }
143
144         /*
145          * all done, let format have a chance to cleanup, and make sure that
146          * the patterns supplied by the user were all matched
147          */
148         (void)(*frmt->end_rd)();
149         (void)sigprocmask(SIG_BLOCK, &s_mask, NULL);
150         ar_close();
151         pat_chk();
152 }
153
154 /*
155  * extract()
156  *      extract the member(s) of an archive as specified by user supplied
157  *      pattern(s) (no patterns extracts all members)
158  */
159
160 #ifdef __STDC__
161 void
162 extract(void)
163 #else
164 void
165 extract()
166 #endif
167 {
168         register ARCHD *arcn;
169         register int res;
170         off_t cnt;
171         ARCHD archd;
172         struct stat sb;
173         int fd;
174         time_t now;
175
176         arcn = &archd;
177         /*
178          * figure out archive type; pass any format specific options to the
179          * archive option processing routine; call the format init routine;
180          * start up the directory modification time and access mode database
181          */
182         if ((get_arc() < 0) || ((*frmt->options)() < 0) ||
183             ((*frmt->st_rd)() < 0) || (dir_start() < 0))
184                 return;
185
186         /*
187          * When we are doing interactive rename, we store the mapping of names
188          * so we can fix up hard links files later in the archive.
189          */
190         if (iflag && (name_start() < 0))
191                 return;
192
193         now = time(NULL);
194
195         /*
196          * step through each entry on the archive until the format read routine
197          * says it is done
198          */
199         while (next_head(arcn) == 0) {
200
201                 /*
202                  * check for pattern, and user specified options match. When
203                  * all the patterns are matched we are done
204                  */
205                 if ((res = pat_match(arcn)) < 0)
206                         break;
207
208                 if ((res > 0) || (sel_chk(arcn) != 0)) {
209                         /*
210                          * file is not selected. skip past any file data and
211                          * padding and go back for the next archive member
212                          */
213                         (void)rd_skip(arcn->skip + arcn->pad);
214                         continue;
215                 }
216
217                 /*
218                  * with -u or -D only extract when the archive member is newer
219                  * than the file with the same name in the file system (nos
220                  * test of being the same type is required).
221                  * NOTE: this test is done BEFORE name modifications as
222                  * specified by pax. this operation can be confusing to the
223                  * user who might expect the test to be done on an existing
224                  * file AFTER the name mod. In honesty the pax spec is probably
225                  * flawed in this respect.
226                  */
227                 if ((uflag || Dflag) && ((lstat(arcn->name, &sb) == 0))) {
228                         if (uflag && Dflag) {
229                                 if ((arcn->sb.st_mtime <= sb.st_mtime) &&
230                                     (arcn->sb.st_ctime <= sb.st_ctime)) {
231                                         (void)rd_skip(arcn->skip + arcn->pad);
232                                         continue;
233                                 }
234                         } else if (Dflag) {
235                                 if (arcn->sb.st_ctime <= sb.st_ctime) {
236                                         (void)rd_skip(arcn->skip + arcn->pad);
237                                         continue;
238                                 }
239                         } else if (arcn->sb.st_mtime <= sb.st_mtime) {
240                                 (void)rd_skip(arcn->skip + arcn->pad);
241                                 continue;
242                         }
243                 }
244
245                 /*
246                  * this archive member is now been selected. modify the name.
247                  */
248                 if ((pat_sel(arcn) < 0) || ((res = mod_name(arcn)) < 0))
249                         break;
250                 if (res > 0) {
251                         /*
252                          * a bad name mod, skip and purge name from link table
253                          */
254                         purg_lnk(arcn);
255                         (void)rd_skip(arcn->skip + arcn->pad);
256                         continue;
257                 }
258
259                 /*
260                  * Non standard -Y and -Z flag. When the existing file is
261                  * same age or newer skip
262                  */
263                 if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
264                         if (Yflag && Zflag) {
265                                 if ((arcn->sb.st_mtime <= sb.st_mtime) &&
266                                     (arcn->sb.st_ctime <= sb.st_ctime)) {
267                                         (void)rd_skip(arcn->skip + arcn->pad);
268                                         continue;
269                                 }
270                         } else if (Yflag) {
271                                 if (arcn->sb.st_ctime <= sb.st_ctime) {
272                                         (void)rd_skip(arcn->skip + arcn->pad);
273                                         continue;
274                                 }
275                         } else if (arcn->sb.st_mtime <= sb.st_mtime) {
276                                 (void)rd_skip(arcn->skip + arcn->pad);
277                                 continue;
278                         }
279                 }
280
281                 if (vflag) {
282                         if (vflag > 1)
283                                 ls_list(arcn, now, listf);
284                         else {
285                                 (void)fputs(arcn->name, listf);
286                                 vfpart = 1;
287                         }
288                 }
289
290                 /*
291                  * if required, chdir around.
292                  */
293                 if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
294                         if (chdir(arcn->pat->chdname) != 0)
295                                 syswarn(1, errno, "Cannot chdir to %s",
296                                     arcn->pat->chdname);
297
298                 /*
299                  * all ok, extract this member based on type
300                  */
301                 if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {
302                         /*
303                          * process archive members that are not regular files.
304                          * throw out padding and any data that might follow the
305                          * header (as determined by the format).
306                          */
307                         if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
308                                 res = lnk_creat(arcn);
309                         else
310                                 res = node_creat(arcn);
311
312                         (void)rd_skip(arcn->skip + arcn->pad);
313                         if (res < 0)
314                                 purg_lnk(arcn);
315
316                         if (vflag && vfpart) {
317                                 (void)putc('\n', listf);
318                                 vfpart = 0;
319                         }
320                         continue;
321                 }
322                 /*
323                  * we have a file with data here. If we can not create it, skip
324                  * over the data and purge the name from hard link table
325                  */
326                 if ((fd = file_creat(arcn)) < 0) {
327                         (void)rd_skip(arcn->skip + arcn->pad);
328                         purg_lnk(arcn);
329                         continue;
330                 }
331                 /*
332                  * extract the file from the archive and skip over padding and
333                  * any unprocessed data
334                  */
335                 res = (*frmt->rd_data)(arcn, fd, &cnt);
336                 file_close(arcn, fd);
337                 if (vflag && vfpart) {
338                         (void)putc('\n', listf);
339                         vfpart = 0;
340                 }
341                 if (!res)
342                         (void)rd_skip(cnt + arcn->pad);
343
344                 /*
345                  * if required, chdir around.
346                  */
347                 if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL))
348                         if (fchdir(cwdfd) != 0)
349                                 syswarn(1, errno,
350                                     "Can't fchdir to starting directory");
351         }
352
353         /*
354          * all done, restore directory modes and times as required; make sure
355          * all patterns supplied by the user were matched; block off signals
356          * to avoid chance for multiple entry into the cleanup code.
357          */
358         (void)(*frmt->end_rd)();
359         (void)sigprocmask(SIG_BLOCK, &s_mask, NULL);
360         ar_close();
361         proc_dir();
362         pat_chk();
363 }
364
365 /*
366  * wr_archive()
367  *      Write an archive. used in both creating a new archive and appends on
368  *      previously written archive.
369  */
370
371 #ifdef __STDC__
372 static void
373 wr_archive(register ARCHD *arcn, int is_app)
374 #else
375 static void
376 wr_archive(arcn, is_app)
377         register ARCHD *arcn;
378         int is_app;
379 #endif
380 {
381         register int res;
382         register int hlk;
383         register int wr_one;
384         off_t cnt;
385         int (*wrf)();
386         int fd = -1;
387         time_t now;
388
389         /*
390          * if this format supports hard link storage, start up the database
391          * that detects them.
392          */
393         if (((hlk = frmt->hlk) == 1) && (lnk_start() < 0))
394                 return;
395
396         /*
397          * start up the file traversal code and format specific write
398          */
399         if ((ftree_start() < 0) || ((*frmt->st_wr)() < 0))
400                 return;
401         wrf = frmt->wr;
402
403         /*
404          * When we are doing interactive rename, we store the mapping of names
405          * so we can fix up hard links files later in the archive.
406          */
407         if (iflag && (name_start() < 0))
408                 return;
409
410         /*
411          * if this not append, and there are no files, we do no write a trailer
412          */
413         wr_one = is_app;
414
415         now = time(NULL);
416
417         /*
418          * while there are files to archive, process them one at at time
419          */
420         while (next_file(arcn) == 0) {
421                 /*
422                  * check if this file meets user specified options match.
423                  */
424                 if (sel_chk(arcn) != 0)
425                         continue;
426                 fd = -1;
427                 if (uflag) {
428                         /*
429                          * only archive if this file is newer than a file with
430                          * the same name that is already stored on the archive
431                          */
432                         if ((res = chk_ftime(arcn)) < 0)
433                                 break;
434                         if (res > 0)
435                                 continue;
436                 }
437
438                 /*
439                  * this file is considered selected now. see if this is a hard
440                  * link to a file already stored
441                  */
442                 ftree_sel(arcn);
443                 if (hlk && (chk_lnk(arcn) < 0))
444                         break;
445
446                 if ((arcn->type == PAX_REG) || (arcn->type == PAX_HRG) ||
447                     (arcn->type == PAX_CTG)) {
448                         /*
449                          * we will have to read this file. by opening it now we
450                          * can avoid writing a header to the archive for a file
451                          * we were later unable to read (we also purge it from
452                          * the link table).
453                          */
454                         if ((fd = open(arcn->org_name, O_RDONLY, 0)) < 0) {
455                                 syswarn(1,errno, "Unable to open %s to read",
456                                         arcn->org_name);
457                                 purg_lnk(arcn);
458                                 continue;
459                         }
460                 }
461
462                 /*
463                  * Now modify the name as requested by the user
464                  */
465                 if ((res = mod_name(arcn)) < 0) {
466                         /*
467                          * name modification says to skip this file, close the
468                          * file and purge link table entry
469                          */
470                         rdfile_close(arcn, &fd);
471                         purg_lnk(arcn);
472                         break;
473                 }
474
475                 if ((res > 0) || (docrc && (set_crc(arcn, fd) < 0))) {
476                         /*
477                          * unable to obtain the crc we need, close the file,
478                          * purge link table entry
479                          */
480                         rdfile_close(arcn, &fd);
481                         purg_lnk(arcn);
482                         continue;
483                 }
484
485                 if (vflag) {
486                         if (vflag > 1)
487                                 ls_list(arcn, now, listf);
488                         else {
489                                 (void)fputs(arcn->name, listf);
490                                 vfpart = 1;
491                         }
492                 }
493                 ++flcnt;
494
495                 /*
496                  * looks safe to store the file, have the format specific
497                  * routine write routine store the file header on the archive
498                  */
499                 if ((res = (*wrf)(arcn)) < 0) {
500                         rdfile_close(arcn, &fd);
501                         break;
502                 }
503                 wr_one = 1;
504                 if (res > 0) {
505                         /*
506                          * format write says no file data needs to be stored
507                          * so we are done messing with this file
508                          */
509                         if (vflag && vfpart) {
510                                 (void)putc('\n', listf);
511                                 vfpart = 0;
512                         }
513                         rdfile_close(arcn, &fd);
514                         continue;
515                 }
516
517                 /*
518                  * Add file data to the archive, quit on write error. if we
519                  * cannot write the entire file contents to the archive we
520                  * must pad the archive to replace the missing file data
521                  * (otherwise during an extract the file header for the file
522                  * which FOLLOWS this one will not be where we expect it to
523                  * be).
524                  */
525                 res = (*frmt->wr_data)(arcn, fd, &cnt);
526                 rdfile_close(arcn, &fd);
527                 if (vflag && vfpart) {
528                         (void)putc('\n', listf);
529                         vfpart = 0;
530                 }
531                 if (res < 0)
532                         break;
533
534                 /*
535                  * pad as required, cnt is number of bytes not written
536                  */
537                 if (((cnt > 0) && (wr_skip(cnt) < 0)) ||
538                     ((arcn->pad > 0) && (wr_skip(arcn->pad) < 0)))
539                         break;
540         }
541
542         /*
543          * tell format to write trailer; pad to block boundary; reset directory
544          * mode/access times, and check if all patterns supplied by the user
545          * were matched. block off signals to avoid chance for multiple entry
546          * into the cleanup code
547          */
548         if (wr_one) {
549                 (*frmt->end_wr)();
550                 wr_fin();
551         }
552         (void)sigprocmask(SIG_BLOCK, &s_mask, NULL);
553         ar_close();
554         if (tflag)
555                 proc_dir();
556         ftree_chk();
557 }
558
559 /*
560  * append()
561  *      Add file to previously written archive. Archive format specified by the
562  *      user must agree with archive. The archive is read first to collect
563  *      modification times (if -u) and locate the archive trailer. The archive
564  *      is positioned in front of the record with the trailer and wr_archive()
565  *      is called to add the new members.
566  *      PAX IMPLEMENTATION DETAIL NOTE:
567  *      -u is implemented by adding the new members to the end of the archive.
568  *      Care is taken so that these do not end up as links to the older
569  *      version of the same file already stored in the archive. It is expected
570  *      when extraction occurs these newer versions will over-write the older
571  *      ones stored "earlier" in the archive (this may be a bad assumption as
572  *      it depends on the implementation of the program doing the extraction).
573  *      It is really difficult to splice in members without either re-writing
574  *      the entire archive (from the point were the old version was), or having
575  *      assistance of the format specification in terms of a special update
576  *      header that invalidates a previous archive record. The POSIX spec left
577  *      the method used to implement -u unspecified. This pax is able to
578  *      over write existing files that it creates.
579  */
580
581 #ifdef __STDC__
582 void
583 append(void)
584 #else
585 void
586 append()
587 #endif
588 {
589         register ARCHD *arcn;
590         register int res;
591         ARCHD archd;
592         FSUB *orgfrmt;
593         int udev;
594         off_t tlen;
595
596         arcn = &archd;
597         orgfrmt = frmt;
598
599         /*
600          * Do not allow an append operation if the actual archive is of a
601          * different format than the user specified format.
602          */
603         if (get_arc() < 0)
604                 return;
605         if ((orgfrmt != NULL) && (orgfrmt != frmt)) {
606                 paxwarn(1, "Cannot mix current archive format %s with %s",
607                     frmt->name, orgfrmt->name);
608                 return;
609         }
610
611         /*
612          * pass the format any options and start up format
613          */
614         if (((*frmt->options)() < 0) || ((*frmt->st_rd)() < 0))
615                 return;
616
617         /*
618          * if we only are adding members that are newer, we need to save the
619          * mod times for all files we see.
620          */
621         if (uflag && (ftime_start() < 0))
622                 return;
623
624         /*
625          * some archive formats encode hard links by recording the device and
626          * file serial number (inode) but copy the file anyway (multiple times)
627          * to the archive. When we append, we run the risk that newly added
628          * files may have the same device and inode numbers as those recorded
629          * on the archive but during a previous run. If this happens, when the
630          * archive is extracted we get INCORRECT hard links. We avoid this by
631          * remapping the device numbers so that newly added files will never
632          * use the same device number as one found on the archive. remapping
633          * allows new members to safely have links among themselves. remapping
634          * also avoids problems with file inode (serial number) truncations
635          * when the inode number is larger than storage space in the archive
636          * header. See the remap routines for more details.
637          */
638         if ((udev = frmt->udev) && (dev_start() < 0))
639                 return;
640
641         /*
642          * reading the archive may take a long time. If verbose tell the user
643          */
644         if (vflag) {
645                 (void)fprintf(listf,
646                         "%s: Reading archive to position at the end...", argv0);
647                 vfpart = 1;
648         }
649
650         /*
651          * step through the archive until the format says it is done
652          */
653         while (next_head(arcn) == 0) {
654                 /*
655                  * check if this file meets user specified options.
656                  */
657                 if (sel_chk(arcn) != 0) {
658                         if (rd_skip(arcn->skip + arcn->pad) == 1)
659                                 break;
660                         continue;
661                 }
662
663                 if (uflag) {
664                         /*
665                          * see if this is the newest version of this file has
666                          * already been seen, if so skip.
667                          */
668                         if ((res = chk_ftime(arcn)) < 0)
669                                 break;
670                         if (res > 0) {
671                                 if (rd_skip(arcn->skip + arcn->pad) == 1)
672                                         break;
673                                 continue;
674                         }
675                 }
676
677                 /*
678                  * Store this device number. Device numbers seen during the
679                  * read phase of append will cause newly appended files with a
680                  * device number seen in the old part of the archive to be
681                  * remapped to an unused device number.
682                  */
683                 if ((udev && (add_dev(arcn) < 0)) ||
684                     (rd_skip(arcn->skip + arcn->pad) == 1))
685                         break;
686         }
687
688         /*
689          * done, finish up read and get the number of bytes to back up so we
690          * can add new members. The format might have used the hard link table,
691          * purge it.
692          */
693         tlen = (*frmt->end_rd)();
694         lnk_end();
695
696         /*
697          * try to position for write, if this fails quit. if any error occurs,
698          * we will refuse to write
699          */
700         if (appnd_start(tlen) < 0)
701                 return;
702
703         /*
704          * tell the user we are done reading.
705          */
706         if (vflag && vfpart) {
707                 (void)fputs("done.\n", listf);
708                 vfpart = 0;
709         }
710
711         /*
712          * go to the writing phase to add the new members
713          */
714         wr_archive(arcn, 1);
715 }
716
717 /*
718  * archive()
719  *      write a new archive
720  */
721
722 #ifdef __STDC__
723 void
724 archive(void)
725 #else
726 void
727 archive()
728 #endif
729 {
730         ARCHD archd;
731
732         /*
733          * if we only are adding members that are newer, we need to save the
734          * mod times for all files; set up for writing; pass the format any
735          * options write the archive
736          */
737         if ((uflag && (ftime_start() < 0)) || (wr_start() < 0))
738                 return;
739         if ((*frmt->options)() < 0)
740                 return;
741
742         wr_archive(&archd, 0);
743 }
744
745 /*
746  * copy()
747  *      copy files from one part of the file system to another. this does not
748  *      use any archive storage. The EFFECT OF THE COPY IS THE SAME as if an
749  *      archive was written and then extracted in the destination directory
750  *      (except the files are forced to be under the destination directory).
751  */
752
753 #ifdef __STDC__
754 void
755 copy(void)
756 #else
757 void
758 copy()
759 #endif
760 {
761         register ARCHD *arcn;
762         register int res;
763         register int fddest;
764         register char *dest_pt;
765         register int dlen;
766         register int drem;
767         int fdsrc = -1;
768         struct stat sb;
769         ARCHD archd;
770         char dirbuf[PAXPATHLEN+1];
771
772         arcn = &archd;
773         /*
774          * set up the destination dir path and make sure it is a directory. We
775          * make sure we have a trailing / on the destination
776          */
777         dlen = l_strncpy(dirbuf, dirptr, sizeof(dirbuf) - 1);
778         dest_pt = dirbuf + dlen;
779         if (*(dest_pt-1) != '/') {
780                 *dest_pt++ = '/';
781                 ++dlen;
782         }
783         *dest_pt = '\0';
784         drem = PAXPATHLEN - dlen;
785
786         if (stat(dirptr, &sb) < 0) {
787                 syswarn(1, errno, "Cannot access destination directory %s",
788                         dirptr);
789                 return;
790         }
791         if (!S_ISDIR(sb.st_mode)) {
792                 paxwarn(1, "Destination is not a directory %s", dirptr);
793                 return;
794         }
795
796         /*
797          * start up the hard link table; file traversal routines and the
798          * modification time and access mode database
799          */
800         if ((lnk_start() < 0) || (ftree_start() < 0) || (dir_start() < 0))
801                 return;
802
803         /*
804          * When we are doing interactive rename, we store the mapping of names
805          * so we can fix up hard links files later in the archive.
806          */
807         if (iflag && (name_start() < 0))
808                 return;
809
810         /*
811          * set up to cp file trees
812          */
813         cp_start();
814
815         /*
816          * while there are files to archive, process them
817          */
818         while (next_file(arcn) == 0) {
819                 fdsrc = -1;
820
821                 /*
822                  * check if this file meets user specified options
823                  */
824                 if (sel_chk(arcn) != 0)
825                         continue;
826
827                 /*
828                  * if there is already a file in the destination directory with
829                  * the same name and it is newer, skip the one stored on the
830                  * archive.
831                  * NOTE: this test is done BEFORE name modifications as
832                  * specified by pax. this can be confusing to the user who
833                  * might expect the test to be done on an existing file AFTER
834                  * the name mod. In honesty the pax spec is probably flawed in
835                  * this respect
836                  */
837                 if (uflag || Dflag) {
838                         /*
839                          * create the destination name
840                          */
841                         if (*(arcn->name) == '/')
842                                 res = 1;
843                         else
844                                 res = 0;
845                         if ((arcn->nlen - res) > drem) {
846                                 paxwarn(1, "Destination pathname too long %s",
847                                         arcn->name);
848                                 continue;
849                         }
850                         (void)strncpy(dest_pt, arcn->name + res, drem);
851                         dirbuf[PAXPATHLEN] = '\0';
852
853                         /*
854                          * if existing file is same age or newer skip
855                          */
856                         res = lstat(dirbuf, &sb);
857                         *dest_pt = '\0';
858
859                         if (res == 0) {
860                                 if (uflag && Dflag) {
861                                         if ((arcn->sb.st_mtime<=sb.st_mtime) &&
862                                             (arcn->sb.st_ctime<=sb.st_ctime))
863                                                 continue;
864                                 } else if (Dflag) {
865                                         if (arcn->sb.st_ctime <= sb.st_ctime)
866                                                 continue;
867                                 } else if (arcn->sb.st_mtime <= sb.st_mtime)
868                                         continue;
869                         }
870                 }
871
872                 /*
873                  * this file is considered selected. See if this is a hard link
874                  * to a previous file; modify the name as requested by the
875                  * user; set the final destination.
876                  */
877                 ftree_sel(arcn);
878                 if ((chk_lnk(arcn) < 0) || ((res = mod_name(arcn)) < 0))
879                         break;
880                 if ((res > 0) || (set_dest(arcn, dirbuf, dlen) < 0)) {
881                         /*
882                          * skip file, purge from link table
883                          */
884                         purg_lnk(arcn);
885                         continue;
886                 }
887
888                 /*
889                  * Non standard -Y and -Z flag. When the exisiting file is
890                  * same age or newer skip
891                  */
892                 if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
893                         if (Yflag && Zflag) {
894                                 if ((arcn->sb.st_mtime <= sb.st_mtime) &&
895                                     (arcn->sb.st_ctime <= sb.st_ctime))
896                                         continue;
897                         } else if (Yflag) {
898                                 if (arcn->sb.st_ctime <= sb.st_ctime)
899                                         continue;
900                         } else if (arcn->sb.st_mtime <= sb.st_mtime)
901                                 continue;
902                 }
903
904                 if (vflag) {
905                         (void)fputs(arcn->name, listf);
906                         vfpart = 1;
907                 }
908                 ++flcnt;
909
910                 /*
911                  * try to create a hard link to the src file if requested
912                  * but make sure we are not trying to overwrite ourselves.
913                  */
914                 if (lflag)
915                         res = cross_lnk(arcn);
916                 else
917                         res = chk_same(arcn);
918                 if (res <= 0) {
919                         if (vflag && vfpart) {
920                                 (void)putc('\n', listf);
921                                 vfpart = 0;
922                         }
923                         continue;
924                 }
925
926                 /*
927                  * have to create a new file
928                  */
929                 if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {
930                         /*
931                          * create a link or special file
932                          */
933                         if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG))
934                                 res = lnk_creat(arcn);
935                         else
936                                 res = node_creat(arcn);
937                         if (res < 0)
938                                 purg_lnk(arcn);
939                         if (vflag && vfpart) {
940                                 (void)putc('\n', listf);
941                                 vfpart = 0;
942                         }
943                         continue;
944                 }
945
946                 /*
947                  * have to copy a regular file to the destination directory.
948                  * first open source file and then create the destination file
949                  */
950                 if ((fdsrc = open(arcn->org_name, O_RDONLY, 0)) < 0) {
951                         syswarn(1, errno, "Unable to open %s to read",
952                             arcn->org_name);
953                         purg_lnk(arcn);
954                         continue;
955                 }
956                 if ((fddest = file_creat(arcn)) < 0) {
957                         rdfile_close(arcn, &fdsrc);
958                         purg_lnk(arcn);
959                         continue;
960                 }
961
962                 /*
963                  * copy source file data to the destination file
964                  */
965                 cp_file(arcn, fdsrc, fddest);
966                 file_close(arcn, fddest);
967                 rdfile_close(arcn, &fdsrc);
968
969                 if (vflag && vfpart) {
970                         (void)putc('\n', listf);
971                         vfpart = 0;
972                 }
973         }
974
975         /*
976          * restore directory modes and times as required; make sure all
977          * patterns were selected block off signals to avoid chance for
978          * multiple entry into the cleanup code.
979          */
980         (void)sigprocmask(SIG_BLOCK, &s_mask, NULL);
981         ar_close();
982         proc_dir();
983         ftree_chk();
984 }
985
986 /*
987  * next_head()
988  *      try to find a valid header in the archive. Uses format specific
989  *      routines to extract the header and id the trailer. Trailers may be
990  *      located within a valid header or in an invalid header (the location
991  *      is format specific. The inhead field from the option table tells us
992  *      where to look for the trailer).
993  *      We keep reading (and resyncing) until we get enough contiguous data
994  *      to check for a header. If we cannot find one, we shift by a byte
995  *      add a new byte from the archive to the end of the buffer and try again.
996  *      If we get a read error, we throw out what we have (as we must have
997  *      contiguous data) and start over again.
998  *      ASSUMED: headers fit within a BLKMULT header.
999  * Return:
1000  *      0 if we got a header, -1 if we are unable to ever find another one
1001  *      (we reached the end of input, or we reached the limit on retries. see
1002  *      the specs for rd_wrbuf() for more details)
1003  */
1004
1005 #ifdef __STDC__
1006 static int
1007 next_head(register ARCHD *arcn)
1008 #else
1009 static int
1010 next_head(arcn)
1011         register ARCHD *arcn;
1012 #endif
1013 {
1014         register int ret;
1015         register char *hdend;
1016         register int res;
1017         register int shftsz;
1018         register int hsz;
1019         register int in_resync = 0;     /* set when we are in resync mode */
1020         int cnt = 0;                    /* counter for trailer function */
1021         int first = 1;                  /* on 1st read, EOF isn't premature. */
1022
1023         /*
1024          * set up initial conditions, we want a whole frmt->hsz block as we
1025          * have no data yet.
1026          */
1027         res = hsz = frmt->hsz;
1028         hdend = hdbuf;
1029         shftsz = hsz - 1;
1030         for(;;) {
1031                 /*
1032                  * keep looping until we get a contiguous FULL buffer
1033                  * (frmt->hsz is the proper size)
1034                  */
1035                 for (;;) {
1036                         if ((ret = rd_wrbuf(hdend, res)) == res)
1037                                 break;
1038
1039                         /*
1040                          * If we read 0 bytes (EOF) from an archive when we
1041                          * expect to find a header, we have stepped upon
1042                          * an archive without the customary block of zeroes
1043                          * end marker.  It's just stupid to error out on
1044                          * them, so exit gracefully.
1045                          */
1046                         if (first && ret == 0)
1047                                 return(-1);
1048                         first = 0;
1049
1050                         /*
1051                          * some kind of archive read problem, try to resync the
1052                          * storage device, better give the user the bad news.
1053                          */
1054                         if ((ret == 0) || (rd_sync() < 0)) {
1055                                 paxwarn(1,"Premature end of file on archive read");
1056                                 return(-1);
1057                         }
1058                         if (!in_resync) {
1059                                 if (act == APPND) {
1060                                         paxwarn(1,
1061                                           "Archive I/O error, cannot continue");
1062                                         return(-1);
1063                                 }
1064                                 paxwarn(1,"Archive I/O error. Trying to recover.");
1065                                 ++in_resync;
1066                         }
1067
1068                         /*
1069                          * oh well, throw it all out and start over
1070                          */
1071                         res = hsz;
1072                         hdend = hdbuf;
1073                 }
1074
1075                 /*
1076                  * ok we have a contiguous buffer of the right size. Call the
1077                  * format read routine. If this was not a valid header and this
1078                  * format stores trailers outside of the header, call the
1079                  * format specific trailer routine to check for a trailer. We
1080                  * have to watch out that we do not mis-identify file data or
1081                  * block padding as a header or trailer. Format specific
1082                  * trailer functions must NOT check for the trailer while we
1083                  * are running in resync mode. Some trailer functions may tell
1084                  * us that this block cannot contain a valid header either, so
1085                  * we then throw out the entire block and start over.
1086                  */
1087                 if ((*frmt->rd)(arcn, hdbuf) == 0)
1088                         break;
1089
1090                 if (!frmt->inhead) {
1091                         /*
1092                          * this format has trailers outside of valid headers
1093                          */
1094                         if ((ret = (*frmt->trail)(hdbuf,in_resync,&cnt)) == 0){
1095                                 /*
1096                                  * valid trailer found, drain input as required
1097                                  */
1098                                 ar_drain();
1099                                 return(-1);
1100                         }
1101
1102                         if (ret == 1) {
1103                                 /*
1104                                  * we are in resync and we were told to throw
1105                                  * the whole block out because none of the
1106                                  * bytes in this block can be used to form a
1107                                  * valid header
1108                                  */
1109                                 res = hsz;
1110                                 hdend = hdbuf;
1111                                 continue;
1112                         }
1113                 }
1114
1115                 /*
1116                  * Brute force section.
1117                  * not a valid header. We may be able to find a header yet. So
1118                  * we shift over by one byte, and set up to read one byte at a
1119                  * time from the archive and place it at the end of the buffer.
1120                  * We will keep moving byte at a time until we find a header or
1121                  * get a read error and have to start over.
1122                  */
1123                 if (!in_resync) {
1124                         if (act == APPND) {
1125                                 paxwarn(1,"Unable to append, archive header flaw");
1126                                 return(-1);
1127                         }
1128                         paxwarn(1,"Invalid header, starting valid header search.");
1129                         ++in_resync;
1130                 }
1131                 memmove(hdbuf, hdbuf+1, shftsz);
1132                 res = 1;
1133                 hdend = hdbuf + shftsz;
1134         }
1135
1136         /*
1137          * ok got a valid header, check for trailer if format encodes it in the
1138          * the header. NOTE: the parameters are different than trailer routines
1139          * which encode trailers outside of the header!
1140          */
1141         if (frmt->inhead && ((*frmt->trail)(arcn) == 0)) {
1142                 /*
1143                  * valid trailer found, drain input as required
1144                  */
1145                 ar_drain();
1146                 return(-1);
1147         }
1148
1149         ++flcnt;
1150         return(0);
1151 }
1152
1153 /*
1154  * get_arc()
1155  *      Figure out what format an archive is. Handles archive with flaws by
1156  *      brute force searches for a legal header in any supported format. The
1157  *      format id routines have to be careful to NOT mis-identify a format.
1158  *      ASSUMED: headers fit within a BLKMULT header.
1159  * Return:
1160  *      0 if archive found -1 otherwise
1161  */
1162
1163 #ifdef __STDC__
1164 static int
1165 get_arc(void)
1166 #else
1167 static int
1168 get_arc()
1169 #endif
1170 {
1171         register int i;
1172         register int hdsz = 0;
1173         register int res;
1174         register int minhd = BLKMULT;
1175         char *hdend;
1176         int notice = 0;
1177
1178         /*
1179          * find the smallest header size in all archive formats and then set up
1180          * to read the archive.
1181          */
1182         for (i = 0; ford[i] >= 0; ++i) {
1183                 if (fsub[ford[i]].hsz < minhd)
1184                         minhd = fsub[ford[i]].hsz;
1185         }
1186         if (rd_start() < 0)
1187                 return(-1);
1188         res = BLKMULT;
1189         hdsz = 0;
1190         hdend = hdbuf;
1191         for(;;) {
1192                 for (;;) {
1193                         /*
1194                          * fill the buffer with at least the smallest header
1195                          */
1196                         i = rd_wrbuf(hdend, res);
1197                         if (i > 0)
1198                                 hdsz += i;
1199                         if (hdsz >= minhd)
1200                                 break;
1201
1202                         /*
1203                          * if we cannot recover from a read error quit
1204                          */
1205                         if ((i == 0) || (rd_sync() < 0))
1206                                 goto out;
1207
1208                         /*
1209                          * when we get an error none of the data we already
1210                          * have can be used to create a legal header (we just
1211                          * got an error in the middle), so we throw it all out
1212                          * and refill the buffer with fresh data.
1213                          */
1214                         res = BLKMULT;
1215                         hdsz = 0;
1216                         hdend = hdbuf;
1217                         if (!notice) {
1218                                 if (act == APPND)
1219                                         return(-1);
1220                                 paxwarn(1,"Cannot identify format. Searching...");
1221                                 ++notice;
1222                         }
1223                 }
1224
1225                 /*
1226                  * we have at least the size of the smallest header in any
1227                  * archive format. Look to see if we have a match. The array
1228                  * ford[] is used to specify the header id order to reduce the
1229                  * chance of incorrectly id'ing a valid header (some formats
1230                  * may be subsets of each other and the order would then be
1231                  * important).
1232                  */
1233                 for (i = 0; ford[i] >= 0; ++i) {
1234                         if ((*fsub[ford[i]].id)(hdbuf, hdsz) < 0)
1235                                 continue;
1236                         frmt = &(fsub[ford[i]]);
1237                         /*
1238                          * yuck, to avoid slow special case code in the extract
1239                          * routines, just push this header back as if it was
1240                          * not seen. We have left extra space at start of the
1241                          * buffer for this purpose. This is a bit ugly, but
1242                          * adding all the special case code is far worse.
1243                          */
1244                         pback(hdbuf, hdsz);
1245                         return(0);
1246                 }
1247
1248                 /*
1249                  * We have a flawed archive, no match. we start searching, but
1250                  * we never allow additions to flawed archives
1251                  */
1252                 if (!notice) {
1253                         if (act == APPND)
1254                                 return(-1);
1255                         paxwarn(1, "Cannot identify format. Searching...");
1256                         ++notice;
1257                 }
1258
1259                 /*
1260                  * brute force search for a header that we can id.
1261                  * we shift through byte at a time. this is slow, but we cannot
1262                  * determine the nature of the flaw in the archive in a
1263                  * portable manner
1264                  */
1265                 if (--hdsz > 0) {
1266                         memmove(hdbuf, hdbuf+1, hdsz);
1267                         res = BLKMULT - hdsz;
1268                         hdend = hdbuf + hdsz;
1269                 } else {
1270                         res = BLKMULT;
1271                         hdend = hdbuf;
1272                         hdsz = 0;
1273                 }
1274         }
1275
1276     out:
1277         /*
1278          * we cannot find a header, bow, apologize and quit
1279          */
1280         paxwarn(1, "Sorry, unable to determine archive format.");
1281         return(-1);
1282 }