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