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