ar.c revision 38889
1/* ar.c - Archive modify and extract. 2 Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. 3 4This file is part of GNU Binutils. 5 6This program is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 2 of the License, or 9(at your option) any later version. 10 11This program is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with this program; if not, write to the Free Software 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 19 20/* 21 Bugs: should use getopt the way tar does (complete w/optional -) and 22 should have long options too. GNU ar used to check file against filesystem 23 in quick_update and replace operations (would check mtime). Doesn't warn 24 when name truncated. No way to specify pos_end. Error messages should be 25 more consistant. 26*/ 27#include "bfd.h" 28#include "libiberty.h" 29#include "progress.h" 30#include "bucomm.h" 31#include "aout/ar.h" 32#include "libbfd.h" 33#include "arsup.h" 34#include <sys/stat.h> 35 36#ifdef HAVE_GOOD_UTIME_H 37#include <utime.h> 38#else /* ! HAVE_GOOD_UTIME_H */ 39#ifdef HAVE_UTIMES 40#include <sys/time.h> 41#endif /* HAVE_UTIMES */ 42#endif /* ! HAVE_GOOD_UTIME_H */ 43 44#ifdef __GO32___ 45#define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */ 46#else 47#define EXT_NAME_LEN 6 /* ditto for *NIX */ 48#endif 49 50#define BUFSIZE 8192 51 52/* Kludge declaration from BFD! This is ugly! FIXME! XXX */ 53 54struct ar_hdr * 55 bfd_special_undocumented_glue PARAMS ((bfd * abfd, const char *filename)); 56 57/* Static declarations */ 58 59static void 60mri_emul PARAMS ((void)); 61 62static const char * 63normalize PARAMS ((const char *, bfd *)); 64 65static void 66remove_output PARAMS ((void)); 67 68static void 69map_over_members PARAMS ((bfd *, void (*)(bfd *), char **, int)); 70 71static void 72print_contents PARAMS ((bfd * member)); 73 74static void 75delete_members PARAMS ((bfd *, char **files_to_delete)); 76 77#if 0 78static void 79do_quick_append PARAMS ((const char *archive_filename, 80 char **files_to_append)); 81#endif 82 83static void 84move_members PARAMS ((bfd *, char **files_to_move)); 85 86static void 87replace_members PARAMS ((bfd *, char **files_to_replace, boolean quick)); 88 89static void 90print_descr PARAMS ((bfd * abfd)); 91 92static void 93write_archive PARAMS ((bfd *)); 94 95static void 96ranlib_only PARAMS ((const char *archname)); 97 98static void 99ranlib_touch PARAMS ((const char *archname)); 100 101static void 102usage PARAMS ((int)); 103 104/** Globals and flags */ 105 106int mri_mode; 107 108/* This flag distinguishes between ar and ranlib: 109 1 means this is 'ranlib'; 0 means this is 'ar'. 110 -1 means if we should use argv[0] to decide. */ 111extern int is_ranlib; 112 113/* Nonzero means don't warn about creating the archive file if necessary. */ 114int silent_create = 0; 115 116/* Nonzero means describe each action performed. */ 117int verbose = 0; 118 119/* Nonzero means preserve dates of members when extracting them. */ 120int preserve_dates = 0; 121 122/* Nonzero means don't replace existing members whose dates are more recent 123 than the corresponding files. */ 124int newer_only = 0; 125 126/* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF 127 member). -1 means we've been explicitly asked to not write a symbol table; 128 +1 means we've been explictly asked to write it; 129 0 is the default. 130 Traditionally, the default in BSD has been to not write the table. 131 However, for POSIX.2 compliance the default is now to write a symbol table 132 if any of the members are object files. */ 133int write_armap = 0; 134 135/* Nonzero means it's the name of an existing member; position new or moved 136 files with respect to this one. */ 137char *posname = NULL; 138 139/* Sez how to use `posname': pos_before means position before that member. 140 pos_after means position after that member. pos_end means always at end. 141 pos_default means default appropriately. For the latter two, `posname' 142 should also be zero. */ 143enum pos 144 { 145 pos_default, pos_before, pos_after, pos_end 146 } postype = pos_default; 147 148static bfd ** 149get_pos_bfd PARAMS ((bfd **, enum pos, const char *)); 150 151/* Whether to truncate names of files stored in the archive. */ 152static boolean ar_truncate = false; 153 154int interactive = 0; 155 156static void 157mri_emul () 158{ 159 interactive = isatty (fileno (stdin)); 160 yyparse (); 161} 162 163/* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero, 164 COUNT is the length of the FILES chain; FUNCTION is called on each entry 165 whose name matches one in FILES. */ 166 167static void 168map_over_members (arch, function, files, count) 169 bfd *arch; 170 void (*function) PARAMS ((bfd *)); 171 char **files; 172 int count; 173{ 174 bfd *head; 175 176 if (count == 0) 177 { 178 for (head = arch->next; head; head = head->next) 179 { 180 PROGRESS (1); 181 function (head); 182 } 183 return; 184 } 185 /* This may appear to be a baroque way of accomplishing what we want. 186 However we have to iterate over the filenames in order to notice where 187 a filename is requested but does not exist in the archive. Ditto 188 mapping over each file each time -- we want to hack multiple 189 references. */ 190 191 for (; count > 0; files++, count--) 192 { 193 boolean found = false; 194 195 for (head = arch->next; head; head = head->next) 196 { 197 PROGRESS (1); 198 if (head->filename == NULL) 199 { 200 /* Some archive formats don't get the filenames filled in 201 until the elements are opened. */ 202 struct stat buf; 203 bfd_stat_arch_elt (head, &buf); 204 } 205 if ((head->filename != NULL) && 206 (!strcmp (*files, head->filename))) 207 { 208 found = true; 209 function (head); 210 } 211 } 212 if (!found) 213 fprintf (stderr, "no entry %s in archive\n", *files); 214 } 215} 216 217boolean operation_alters_arch = false; 218 219static void 220usage (help) 221 int help; 222{ 223 FILE *s; 224 225 s = help ? stdout : stderr; 226 if (! is_ranlib) 227 fprintf (s, "\ 228Usage: %s [-]{dmpqrtx}[abcilosSuvV] [member-name] archive-file file...\n\ 229 %s -M [<mri-script]\n", 230 program_name, program_name); 231 else 232 fprintf (s, "\ 233Usage: %s [-vV] archive\n", program_name); 234 235 list_supported_targets (program_name, stderr); 236 237 if (help) 238 fprintf (s, "Report bugs to bug-gnu-utils@gnu.org\n"); 239 240 xexit (help ? 0 : 1); 241} 242 243/* Normalize a file name specified on the command line into a file 244 name which we will use in an archive. */ 245 246static const char * 247normalize (file, abfd) 248 const char *file; 249 bfd *abfd; 250{ 251 const char *filename; 252 253 filename = strrchr (file, '/'); 254 if (filename != (char *) NULL) 255 filename++; 256 else 257 filename = file; 258 259 if (ar_truncate 260 && abfd != NULL 261 && strlen (filename) > abfd->xvec->ar_max_namelen) 262 { 263 char *s; 264 265 /* Space leak. */ 266 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1); 267 memcpy (s, filename, abfd->xvec->ar_max_namelen); 268 s[abfd->xvec->ar_max_namelen] = '\0'; 269 filename = s; 270 } 271 272 return filename; 273} 274 275/* Remove any output file. This is only called via xatexit. */ 276 277static char *output_filename = NULL; 278static FILE *output_file = NULL; 279static bfd *output_bfd = NULL; 280 281static void 282remove_output () 283{ 284 if (output_filename != NULL) 285 { 286 if (output_bfd != NULL && output_bfd->iostream != NULL) 287 fclose ((FILE *) (output_bfd->iostream)); 288 if (output_file != NULL) 289 fclose (output_file); 290 unlink (output_filename); 291 } 292} 293 294/* The option parsing should be in its own function. 295 It will be when I have getopt working. */ 296 297int 298main (argc, argv) 299 int argc; 300 char **argv; 301{ 302 char *arg_ptr; 303 char c; 304 enum 305 { 306 none = 0, delete, replace, print_table, 307 print_files, extract, move, quick_append 308 } operation = none; 309 int arg_index; 310 char **files; 311 char *inarch_filename; 312 int show_version; 313 314 program_name = argv[0]; 315 xmalloc_set_program_name (program_name); 316 317 if (is_ranlib < 0) 318 { 319 char *temp; 320 321 temp = strrchr (program_name, '/'); 322 if (temp == NULL) 323 temp = program_name; 324 else 325 ++temp; 326 if (strlen (temp) >= 6 327 && strcmp (temp + strlen (temp) - 6, "ranlib") == 0) 328 is_ranlib = 1; 329 else 330 is_ranlib = 0; 331 } 332 333 if (argc > 1 && argv[1][0] == '-') 334 { 335 if (strcmp (argv[1], "--help") == 0) 336 usage (1); 337 else if (strcmp (argv[1], "--version") == 0) 338 { 339 if (is_ranlib) 340 print_version ("ranlib"); 341 else 342 print_version ("ar"); 343 } 344 } 345 346 START_PROGRESS (program_name, 0); 347 348 bfd_init (); 349 set_default_bfd_target (); 350 351 show_version = 0; 352 353 xatexit (remove_output); 354 355 if (is_ranlib) 356 { 357 boolean touch = false; 358 359 if (argc < 2 || strcmp (argv[1], "--help") == 0) 360 usage (0); 361 if (strcmp (argv[1], "-V") == 0 362 || strcmp (argv[1], "-v") == 0 363 || strncmp (argv[1], "--v", 3) == 0) 364 print_version ("ranlib"); 365 arg_index = 1; 366 if (strcmp (argv[1], "-t") == 0) 367 { 368 ++arg_index; 369 touch = true; 370 } 371 while (arg_index < argc) 372 { 373 if (! touch) 374 ranlib_only (argv[arg_index]); 375 else 376 ranlib_touch (argv[arg_index]); 377 ++arg_index; 378 } 379 xexit (0); 380 } 381 382 if (argc == 2 && strcmp (argv[1], "-M") == 0) 383 { 384 mri_emul (); 385 xexit (0); 386 } 387 388 if (argc < 2) 389 usage (0); 390 391 arg_ptr = argv[1]; 392 393 if (*arg_ptr == '-') 394 ++arg_ptr; /* compatibility */ 395 396 while ((c = *arg_ptr++) != '\0') 397 { 398 switch (c) 399 { 400 case 'd': 401 case 'm': 402 case 'p': 403 case 'q': 404 case 'r': 405 case 't': 406 case 'x': 407 if (operation != none) 408 fatal ("two different operation options specified"); 409 switch (c) 410 { 411 case 'd': 412 operation = delete; 413 operation_alters_arch = true; 414 break; 415 case 'm': 416 operation = move; 417 operation_alters_arch = true; 418 break; 419 case 'p': 420 operation = print_files; 421 break; 422 case 'q': 423 operation = quick_append; 424 operation_alters_arch = true; 425 break; 426 case 'r': 427 operation = replace; 428 operation_alters_arch = true; 429 break; 430 case 't': 431 operation = print_table; 432 break; 433 case 'x': 434 operation = extract; 435 break; 436 } 437 case 'l': 438 break; 439 case 'c': 440 silent_create = 1; 441 break; 442 case 'o': 443 preserve_dates = 1; 444 break; 445 case 'V': 446 show_version = true; 447 break; 448 case 's': 449 write_armap = 1; 450 break; 451 case 'S': 452 write_armap = -1; 453 break; 454 case 'u': 455 newer_only = 1; 456 break; 457 case 'v': 458 verbose = 1; 459 break; 460 case 'a': 461 postype = pos_after; 462 break; 463 case 'b': 464 postype = pos_before; 465 break; 466 case 'i': 467 postype = pos_before; 468 break; 469 case 'M': 470 mri_mode = 1; 471 break; 472 case 'f': 473 ar_truncate = true; 474 break; 475 default: 476 fprintf (stderr, "%s: illegal option -- %c\n", program_name, c); 477 usage (0); 478 } 479 } 480 481 if (show_version) 482 print_version ("ar"); 483 484 if (argc < 3) 485 usage (0); 486 487 if (mri_mode) 488 { 489 mri_emul (); 490 } 491 else 492 { 493 bfd *arch; 494 495 /* We can't write an armap when using ar q, so just do ar r 496 instead. */ 497 if (operation == quick_append && write_armap) 498 operation = replace; 499 500 if ((operation == none || operation == print_table) 501 && write_armap == 1) 502 { 503 ranlib_only (argv[2]); 504 xexit (0); 505 } 506 507 if (operation == none) 508 fatal ("no operation specified"); 509 510 if (newer_only && operation != replace) 511 fatal ("`u' is only meaningful with the `r' option."); 512 513 arg_index = 2; 514 515 if (postype != pos_default) 516 posname = argv[arg_index++]; 517 518 inarch_filename = argv[arg_index++]; 519 520 files = arg_index < argc ? argv + arg_index : NULL; 521 522#if 0 523 /* We don't use do_quick_append any more. Too many systems 524 expect ar to always rebuild the symbol table even when q is 525 used. */ 526 527 /* We can't do a quick append if we need to construct an 528 extended name table, because do_quick_append won't be able to 529 rebuild the name table. Unfortunately, at this point we 530 don't actually know the maximum name length permitted by this 531 object file format. So, we guess. FIXME. */ 532 if (operation == quick_append && ! ar_truncate) 533 { 534 char **chk; 535 536 for (chk = files; chk != NULL && *chk != '\0'; chk++) 537 { 538 if (strlen (normalize (*chk, (bfd *) NULL)) > 14) 539 { 540 operation = replace; 541 break; 542 } 543 } 544 } 545 546 if (operation == quick_append) 547 { 548 /* Note that quick appending to a non-existent archive creates it, 549 even if there are no files to append. */ 550 do_quick_append (inarch_filename, files); 551 xexit (0); 552 } 553#endif 554 555 arch = open_inarch (inarch_filename, 556 files == NULL ? (char *) NULL : files[0]); 557 558 switch (operation) 559 { 560 case print_table: 561 map_over_members (arch, print_descr, files, argc - 3); 562 break; 563 564 case print_files: 565 map_over_members (arch, print_contents, files, argc - 3); 566 break; 567 568 case extract: 569 map_over_members (arch, extract_file, files, argc - 3); 570 break; 571 572 case delete: 573 if (files != NULL) 574 delete_members (arch, files); 575 break; 576 577 case move: 578 if (files != NULL) 579 move_members (arch, files); 580 break; 581 582 case replace: 583 case quick_append: 584 if (files != NULL || write_armap > 0) 585 replace_members (arch, files, operation == quick_append); 586 break; 587 588 /* Shouldn't happen! */ 589 default: 590 fprintf (stderr, "%s: internal error -- this option not implemented\n", 591 program_name); 592 xexit (1); 593 } 594 } 595 596 END_PROGRESS (program_name); 597 598 xexit (0); 599 return 0; 600} 601 602bfd * 603open_inarch (archive_filename, file) 604 const char *archive_filename; 605 const char *file; 606{ 607 const char *target; 608 bfd **last_one; 609 bfd *next_one; 610 struct stat sbuf; 611 bfd *arch; 612 char **matching; 613 614 bfd_set_error (bfd_error_no_error); 615 616 target = NULL; 617 618 if (stat (archive_filename, &sbuf) != 0) 619 { 620#ifndef __GO32__ 621 622/* KLUDGE ALERT! Temporary fix until I figger why 623 * stat() is wrong ... think it's buried in GO32's IDT 624 * - Jax 625 */ 626 if (errno != ENOENT) 627 bfd_fatal (archive_filename); 628#endif 629 630 if (!operation_alters_arch) 631 { 632 fprintf (stderr, "%s: ", program_name); 633 perror (archive_filename); 634 maybequit (); 635 return NULL; 636 } 637 638 /* Try to figure out the target to use for the archive from the 639 first object on the list. */ 640 if (file != NULL) 641 { 642 bfd *obj; 643 644 obj = bfd_openr (file, NULL); 645 if (obj != NULL) 646 { 647 if (bfd_check_format (obj, bfd_object)) 648 target = bfd_get_target (obj); 649 (void) bfd_close (obj); 650 } 651 } 652 653 /* Create an empty archive. */ 654 arch = bfd_openw (archive_filename, target); 655 if (arch == NULL 656 || ! bfd_set_format (arch, bfd_archive) 657 || ! bfd_close (arch)) 658 bfd_fatal (archive_filename); 659 } 660 661 arch = bfd_openr (archive_filename, target); 662 if (arch == NULL) 663 { 664 bloser: 665 bfd_fatal (archive_filename); 666 } 667 668 if (! bfd_check_format_matches (arch, bfd_archive, &matching)) 669 { 670 bfd_nonfatal (archive_filename); 671 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 672 { 673 list_matching_formats (matching); 674 free (matching); 675 } 676 xexit (1); 677 } 678 679 last_one = &(arch->next); 680 /* Read all the contents right away, regardless. */ 681 for (next_one = bfd_openr_next_archived_file (arch, NULL); 682 next_one; 683 next_one = bfd_openr_next_archived_file (arch, next_one)) 684 { 685 PROGRESS (1); 686 *last_one = next_one; 687 last_one = &next_one->next; 688 } 689 *last_one = (bfd *) NULL; 690 if (bfd_get_error () != bfd_error_no_more_archived_files) 691 goto bloser; 692 return arch; 693} 694 695static void 696print_contents (abfd) 697 bfd *abfd; 698{ 699 int ncopied = 0; 700 char *cbuf = xmalloc (BUFSIZE); 701 struct stat buf; 702 long size; 703 if (bfd_stat_arch_elt (abfd, &buf) != 0) 704 fatal ("internal stat error on %s", bfd_get_filename (abfd)); 705 706 if (verbose) 707 printf ("\n<member %s>\n\n", bfd_get_filename (abfd)); 708 709 bfd_seek (abfd, 0, SEEK_SET); 710 711 size = buf.st_size; 712 while (ncopied < size) 713 { 714 715 int nread; 716 int tocopy = size - ncopied; 717 if (tocopy > BUFSIZE) 718 tocopy = BUFSIZE; 719 720 nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke 721 abstraction! */ 722 if (nread != tocopy) 723 fatal ("%s is not a valid archive", 724 bfd_get_filename (bfd_my_archive (abfd))); 725 fwrite (cbuf, 1, nread, stdout); 726 ncopied += tocopy; 727 } 728 free (cbuf); 729} 730 731/* Extract a member of the archive into its own file. 732 733 We defer opening the new file until after we have read a BUFSIZ chunk of the 734 old one, since we know we have just read the archive header for the old 735 one. Since most members are shorter than BUFSIZ, this means we will read 736 the old header, read the old data, write a new inode for the new file, and 737 write the new data, and be done. This 'optimization' is what comes from 738 sitting next to a bare disk and hearing it every time it seeks. -- Gnu 739 Gilmore */ 740 741void 742extract_file (abfd) 743 bfd *abfd; 744{ 745 FILE *ostream; 746 char *cbuf = xmalloc (BUFSIZE); 747 int nread, tocopy; 748 int ncopied = 0; 749 long size; 750 struct stat buf; 751 if (bfd_stat_arch_elt (abfd, &buf) != 0) 752 fatal ("internal stat error on %s", bfd_get_filename (abfd)); 753 size = buf.st_size; 754 755 if (verbose) 756 printf ("x - %s\n", bfd_get_filename (abfd)); 757 758 bfd_seek (abfd, 0, SEEK_SET); 759 760 ostream = 0; 761 if (size == 0) 762 { 763 /* Seems like an abstraction violation, eh? Well it's OK! */ 764 output_filename = bfd_get_filename (abfd); 765 766 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB); 767 if (!ostream) 768 { 769 perror (bfd_get_filename (abfd)); 770 xexit (1); 771 } 772 773 output_file = ostream; 774 } 775 else 776 while (ncopied < size) 777 { 778 tocopy = size - ncopied; 779 if (tocopy > BUFSIZE) 780 tocopy = BUFSIZE; 781 782 nread = bfd_read (cbuf, 1, tocopy, abfd); 783 if (nread != tocopy) 784 fatal ("%s is not a valid archive", 785 bfd_get_filename (bfd_my_archive (abfd))); 786 787 /* See comment above; this saves disk arm motion */ 788 if (!ostream) 789 { 790 /* Seems like an abstraction violation, eh? Well it's OK! */ 791 output_filename = bfd_get_filename (abfd); 792 793 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB); 794 if (!ostream) 795 { 796 perror (bfd_get_filename (abfd)); 797 xexit (1); 798 } 799 800 output_file = ostream; 801 } 802 fwrite (cbuf, 1, nread, ostream); 803 ncopied += tocopy; 804 } 805 806 fclose (ostream); 807 808 output_file = NULL; 809 output_filename = NULL; 810 811 chmod (bfd_get_filename (abfd), buf.st_mode); 812 813 if (preserve_dates) 814 { 815#ifdef HAVE_GOOD_UTIME_H 816 struct utimbuf tb; 817 tb.actime = buf.st_mtime; 818 tb.modtime = buf.st_mtime; 819 utime (bfd_get_filename (abfd), &tb); /* FIXME check result */ 820#else /* ! HAVE_GOOD_UTIME_H */ 821#ifndef HAVE_UTIMES 822 long tb[2]; 823 tb[0] = buf.st_mtime; 824 tb[1] = buf.st_mtime; 825 utime (bfd_get_filename (abfd), tb); /* FIXME check result */ 826#else /* HAVE_UTIMES */ 827 struct timeval tv[2]; 828 tv[0].tv_sec = buf.st_mtime; 829 tv[0].tv_usec = 0; 830 tv[1].tv_sec = buf.st_mtime; 831 tv[1].tv_usec = 0; 832 utimes (bfd_get_filename (abfd), tv); /* FIXME check result */ 833#endif /* HAVE_UTIMES */ 834#endif /* ! HAVE_GOOD_UTIME_H */ 835 } 836free (cbuf); 837} 838 839#if 0 840 841/* We don't use this anymore. Too many systems expect ar to rebuild 842 the symbol table even when q is used. */ 843 844/* Just do it quickly; don't worry about dups, armap, or anything like that */ 845 846static void 847do_quick_append (archive_filename, files_to_append) 848 const char *archive_filename; 849 char **files_to_append; 850{ 851 FILE *ofile, *ifile; 852 char *buf = xmalloc (BUFSIZE); 853 long tocopy, thistime; 854 bfd *temp; 855 struct stat sbuf; 856 boolean newfile = false; 857 bfd_set_error (bfd_error_no_error); 858 859 if (stat (archive_filename, &sbuf) != 0) 860 { 861 862#ifndef __GO32__ 863 864/* KLUDGE ALERT! Temporary fix until I figger why 865 * stat() is wrong ... think it's buried in GO32's IDT 866 * - Jax 867 */ 868 869 if (errno != ENOENT) 870 bfd_fatal (archive_filename); 871#endif 872 873 newfile = true; 874 } 875 876 ofile = fopen (archive_filename, FOPEN_AUB); 877 if (ofile == NULL) 878 { 879 perror (program_name); 880 xexit (1); 881 } 882 883 temp = bfd_openr (archive_filename, NULL); 884 if (temp == NULL) 885 { 886 bfd_fatal (archive_filename); 887 } 888 if (newfile == false) 889 { 890 if (bfd_check_format (temp, bfd_archive) != true) 891 fatal ("%s is not an archive", archive_filename); 892 } 893 else 894 { 895 fwrite (ARMAG, 1, SARMAG, ofile); 896 if (!silent_create) 897 fprintf (stderr, "%s: creating %s\n", 898 program_name, archive_filename); 899 } 900 901 if (ar_truncate) 902 temp->flags |= BFD_TRADITIONAL_FORMAT; 903 904 /* assume it's an achive, go straight to the end, sans $200 */ 905 fseek (ofile, 0, 2); 906 907 for (; files_to_append && *files_to_append; ++files_to_append) 908 { 909 struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append); 910 if (hdr == NULL) 911 { 912 bfd_fatal (*files_to_append); 913 } 914 915 BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr)); 916 917 ifile = fopen (*files_to_append, FOPEN_RB); 918 if (ifile == NULL) 919 { 920 bfd_nonfatal (*files_to_append); 921 } 922 923 if (stat (*files_to_append, &sbuf) != 0) 924 { 925 bfd_nonfatal (*files_to_append); 926 } 927 928 tocopy = sbuf.st_size; 929 930 /* XXX should do error-checking! */ 931 fwrite (hdr, 1, sizeof (struct ar_hdr), ofile); 932 933 while (tocopy > 0) 934 { 935 thistime = tocopy; 936 if (thistime > BUFSIZE) 937 thistime = BUFSIZE; 938 fread (buf, 1, thistime, ifile); 939 fwrite (buf, 1, thistime, ofile); 940 tocopy -= thistime; 941 } 942 fclose (ifile); 943 if ((sbuf.st_size % 2) == 1) 944 putc ('\012', ofile); 945 } 946 fclose (ofile); 947 bfd_close (temp); 948 free (buf); 949} 950 951#endif /* 0 */ 952 953static void 954write_archive (iarch) 955 bfd *iarch; 956{ 957 bfd *obfd; 958 char *old_name, *new_name; 959 bfd *contents_head = iarch->next; 960 961 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1); 962 strcpy (old_name, bfd_get_filename (iarch)); 963 new_name = make_tempname (old_name); 964 965 output_filename = new_name; 966 967 obfd = bfd_openw (new_name, bfd_get_target (iarch)); 968 969 if (obfd == NULL) 970 bfd_fatal (old_name); 971 972 output_bfd = obfd; 973 974 bfd_set_format (obfd, bfd_archive); 975 976 /* Request writing the archive symbol table unless we've 977 been explicitly requested not to. */ 978 obfd->has_armap = write_armap >= 0; 979 980 if (ar_truncate) 981 { 982 /* This should really use bfd_set_file_flags, but that rejects 983 archives. */ 984 obfd->flags |= BFD_TRADITIONAL_FORMAT; 985 } 986 987 if (bfd_set_archive_head (obfd, contents_head) != true) 988 bfd_fatal (old_name); 989 990 if (!bfd_close (obfd)) 991 bfd_fatal (old_name); 992 993 output_bfd = NULL; 994 output_filename = NULL; 995 996 /* We don't care if this fails; we might be creating the archive. */ 997 bfd_close (iarch); 998 unlink (old_name); 999 1000 if (rename (new_name, old_name) != 0) 1001 bfd_fatal (old_name); 1002} 1003 1004/* Return a pointer to the pointer to the entry which should be rplacd'd 1005 into when altering. DEFAULT_POS should be how to interpret pos_default, 1006 and should be a pos value. */ 1007 1008static bfd ** 1009get_pos_bfd (contents, default_pos, default_posname) 1010 bfd **contents; 1011 enum pos default_pos; 1012 const char *default_posname; 1013{ 1014 bfd **after_bfd = contents; 1015 enum pos realpos; 1016 const char *realposname; 1017 1018 if (postype == pos_default) 1019 { 1020 realpos = default_pos; 1021 realposname = default_posname; 1022 } 1023 else 1024 { 1025 realpos = postype; 1026 realposname = posname; 1027 } 1028 1029 if (realpos == pos_end) 1030 { 1031 while (*after_bfd) 1032 after_bfd = &((*after_bfd)->next); 1033 } 1034 else 1035 { 1036 for (; *after_bfd; after_bfd = &(*after_bfd)->next) 1037 if (strcmp ((*after_bfd)->filename, realposname) == 0) 1038 { 1039 if (realpos == pos_after) 1040 after_bfd = &(*after_bfd)->next; 1041 break; 1042 } 1043 } 1044 return after_bfd; 1045} 1046 1047static void 1048delete_members (arch, files_to_delete) 1049 bfd *arch; 1050 char **files_to_delete; 1051{ 1052 bfd **current_ptr_ptr; 1053 boolean found; 1054 boolean something_changed = false; 1055 for (; *files_to_delete != NULL; ++files_to_delete) 1056 { 1057 /* In a.out systems, the armap is optional. It's also called 1058 __.SYMDEF. So if the user asked to delete it, we should remember 1059 that fact. This isn't quite right for COFF systems (where 1060 __.SYMDEF might be regular member), but it's very unlikely 1061 to be a problem. FIXME */ 1062 1063 if (!strcmp (*files_to_delete, "__.SYMDEF")) 1064 { 1065 arch->has_armap = false; 1066 write_armap = -1; 1067 continue; 1068 } 1069 1070 found = false; 1071 current_ptr_ptr = &(arch->next); 1072 while (*current_ptr_ptr) 1073 { 1074 if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0) 1075 { 1076 found = true; 1077 something_changed = true; 1078 if (verbose) 1079 printf ("d - %s\n", 1080 *files_to_delete); 1081 *current_ptr_ptr = ((*current_ptr_ptr)->next); 1082 goto next_file; 1083 } 1084 else 1085 { 1086 current_ptr_ptr = &((*current_ptr_ptr)->next); 1087 } 1088 } 1089 1090 if (verbose && found == false) 1091 { 1092 printf ("No member named `%s'\n", *files_to_delete); 1093 } 1094 next_file: 1095 ; 1096 } 1097 1098 if (something_changed == true) 1099 { 1100 write_archive (arch); 1101 } 1102} 1103 1104 1105/* Reposition existing members within an archive */ 1106 1107static void 1108move_members (arch, files_to_move) 1109 bfd *arch; 1110 char **files_to_move; 1111{ 1112 bfd **after_bfd; /* New entries go after this one */ 1113 bfd **current_ptr_ptr; /* cdr pointer into contents */ 1114 1115 for (; *files_to_move; ++files_to_move) 1116 { 1117 current_ptr_ptr = &(arch->next); 1118 while (*current_ptr_ptr) 1119 { 1120 bfd *current_ptr = *current_ptr_ptr; 1121 if (strcmp (normalize (*files_to_move, arch), 1122 current_ptr->filename) == 0) 1123 { 1124 /* Move this file to the end of the list - first cut from 1125 where it is. */ 1126 bfd *link; 1127 *current_ptr_ptr = current_ptr->next; 1128 1129 /* Now glue to end */ 1130 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL); 1131 link = *after_bfd; 1132 *after_bfd = current_ptr; 1133 current_ptr->next = link; 1134 1135 if (verbose) 1136 printf ("m - %s\n", *files_to_move); 1137 1138 goto next_file; 1139 } 1140 1141 current_ptr_ptr = &((*current_ptr_ptr)->next); 1142 } 1143 fprintf (stderr, "%s: no entry %s in archive %s!\n", 1144 program_name, *files_to_move, arch->filename); 1145 xexit (1); 1146 next_file:; 1147 } 1148 1149 write_archive (arch); 1150} 1151 1152/* Ought to default to replacing in place, but this is existing practice! */ 1153 1154static void 1155replace_members (arch, files_to_move, quick) 1156 bfd *arch; 1157 char **files_to_move; 1158 boolean quick; 1159{ 1160 boolean changed = false; 1161 bfd **after_bfd; /* New entries go after this one */ 1162 bfd *current; 1163 bfd **current_ptr; 1164 bfd *temp; 1165 1166 while (files_to_move && *files_to_move) 1167 { 1168 if (! quick) 1169 { 1170 current_ptr = &arch->next; 1171 while (*current_ptr) 1172 { 1173 current = *current_ptr; 1174 1175 /* For compatibility with existing ar programs, we 1176 permit the same file to be added multiple times. */ 1177 if (strcmp (normalize (*files_to_move, arch), 1178 normalize (current->filename, arch)) == 0 1179 && current->arelt_data != NULL) 1180 { 1181 if (newer_only) 1182 { 1183 struct stat fsbuf, asbuf; 1184 1185 if (stat (*files_to_move, &fsbuf) != 0) 1186 { 1187 if (errno != ENOENT) 1188 bfd_fatal (*files_to_move); 1189 goto next_file; 1190 } 1191 if (bfd_stat_arch_elt (current, &asbuf) != 0) 1192 fatal ("internal stat error on %s", current->filename); 1193 1194 if (fsbuf.st_mtime <= asbuf.st_mtime) 1195 goto next_file; 1196 } 1197 1198 after_bfd = get_pos_bfd (&arch->next, pos_after, 1199 current->filename); 1200 temp = *after_bfd; 1201 1202 *after_bfd = bfd_openr (*files_to_move, NULL); 1203 if (*after_bfd == (bfd *) NULL) 1204 { 1205 bfd_fatal (*files_to_move); 1206 } 1207 (*after_bfd)->next = temp; 1208 1209 /* snip out this entry from the chain */ 1210 *current_ptr = (*current_ptr)->next; 1211 1212 if (verbose) 1213 { 1214 printf ("r - %s\n", *files_to_move); 1215 } 1216 1217 changed = true; 1218 1219 goto next_file; 1220 } 1221 current_ptr = &(current->next); 1222 } 1223 } 1224 1225 /* Add to the end of the archive. */ 1226 1227 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL); 1228 temp = *after_bfd; 1229 *after_bfd = bfd_openr (*files_to_move, NULL); 1230 if (*after_bfd == (bfd *) NULL) 1231 { 1232 bfd_fatal (*files_to_move); 1233 } 1234 if (verbose) 1235 { 1236 printf ("a - %s\n", *files_to_move); 1237 } 1238 1239 (*after_bfd)->next = temp; 1240 1241 changed = true; 1242 1243 next_file:; 1244 1245 files_to_move++; 1246 } 1247 1248 if (changed) 1249 write_archive (arch); 1250} 1251 1252static void 1253ranlib_only (archname) 1254 const char *archname; 1255{ 1256 bfd *arch; 1257 1258 write_armap = 1; 1259 arch = open_inarch (archname, (char *) NULL); 1260 if (arch == NULL) 1261 xexit (1); 1262 write_archive (arch); 1263} 1264 1265/* Update the timestamp of the symbol map of an archive. */ 1266 1267static void 1268ranlib_touch (archname) 1269 const char *archname; 1270{ 1271#ifdef __GO32__ 1272 /* I don't think updating works on go32. */ 1273 ranlib_only (archname); 1274#else 1275 int f; 1276 bfd *arch; 1277 char **matching; 1278 1279 f = open (archname, O_RDWR, 0); 1280 if (f < 0) 1281 { 1282 bfd_set_error (bfd_error_system_call); 1283 bfd_fatal (archname); 1284 } 1285 1286 arch = bfd_fdopenr (archname, (const char *) NULL, f); 1287 if (arch == NULL) 1288 bfd_fatal (archname); 1289 if (! bfd_check_format_matches (arch, bfd_archive, &matching)) 1290 { 1291 bfd_nonfatal (archname); 1292 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1293 { 1294 list_matching_formats (matching); 1295 free (matching); 1296 } 1297 xexit (1); 1298 } 1299 1300 if (! bfd_has_map (arch)) 1301 fatal ("%s: no archive map to update", archname); 1302 1303 bfd_update_armap_timestamp (arch); 1304 1305 if (! bfd_close (arch)) 1306 bfd_fatal (archname); 1307#endif 1308} 1309 1310/* Things which are interesting to map over all or some of the files: */ 1311 1312static void 1313print_descr (abfd) 1314 bfd *abfd; 1315{ 1316 print_arelt_descr (stdout, abfd, verbose); 1317} 1318