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