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