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