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