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