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