ar.c revision 33965
1/* ar.c - Archive modify and extract. 2 Copyright 1991, 92, 93, 94, 95, 96, 1997 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, 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)); 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}[abcilosuvV] [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@prep.ai.mit.edu\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 'u': 452 newer_only = 1; 453 break; 454 case 'v': 455 verbose = 1; 456 break; 457 case 'a': 458 postype = pos_after; 459 break; 460 case 'b': 461 postype = pos_before; 462 break; 463 case 'i': 464 postype = pos_before; 465 break; 466 case 'M': 467 mri_mode = 1; 468 break; 469 case 'f': 470 ar_truncate = true; 471 break; 472 default: 473 fprintf (stderr, "%s: illegal option -- %c\n", program_name, c); 474 usage (0); 475 } 476 } 477 478 if (show_version) 479 print_version ("ar"); 480 481 if (argc < 3) 482 usage (0); 483 484 if (mri_mode) 485 { 486 mri_emul (); 487 } 488 else 489 { 490 bfd *arch; 491 492 /* We can't write an armap when using ar q, so just do ar r 493 instead. */ 494 if (operation == quick_append && write_armap) 495 operation = replace; 496 497 if ((operation == none || operation == print_table) 498 && write_armap == 1) 499 { 500 ranlib_only (argv[2]); 501 xexit (0); 502 } 503 504 if (operation == none) 505 fatal ("no operation specified"); 506 507 if (newer_only && operation != replace) 508 fatal ("`u' is only meaningful with the `r' option."); 509 510 arg_index = 2; 511 512 if (postype != pos_default) 513 posname = argv[arg_index++]; 514 515 inarch_filename = argv[arg_index++]; 516 517 files = arg_index < argc ? argv + arg_index : NULL; 518 519#if 0 520 /* We don't use do_quick_append any more. Too many systems 521 expect ar to always rebuild the symbol table even when q is 522 used. */ 523 524 /* We can't do a quick append if we need to construct an 525 extended name table, because do_quick_append won't be able to 526 rebuild the name table. Unfortunately, at this point we 527 don't actually know the maximum name length permitted by this 528 object file format. So, we guess. FIXME. */ 529 if (operation == quick_append && ! ar_truncate) 530 { 531 char **chk; 532 533 for (chk = files; chk != NULL && *chk != '\0'; chk++) 534 { 535 if (strlen (normalize (*chk, (bfd *) NULL)) > 14) 536 { 537 operation = replace; 538 break; 539 } 540 } 541 } 542 543 if (operation == quick_append) 544 { 545 /* Note that quick appending to a non-existent archive creates it, 546 even if there are no files to append. */ 547 do_quick_append (inarch_filename, files); 548 xexit (0); 549 } 550#endif 551 552 arch = open_inarch (inarch_filename, 553 files == NULL ? (char *) NULL : files[0]); 554 555 switch (operation) 556 { 557 case print_table: 558 map_over_members (arch, print_descr, files, argc - 3); 559 break; 560 561 case print_files: 562 map_over_members (arch, print_contents, files, argc - 3); 563 break; 564 565 case extract: 566 map_over_members (arch, extract_file, files, argc - 3); 567 break; 568 569 case delete: 570 if (files != NULL) 571 delete_members (arch, files); 572 break; 573 574 case move: 575 if (files != NULL) 576 move_members (arch, files); 577 break; 578 579 case replace: 580 case quick_append: 581 if (files != NULL || write_armap > 0) 582 replace_members (arch, files, operation == quick_append); 583 break; 584 585 /* Shouldn't happen! */ 586 default: 587 fprintf (stderr, "%s: internal error -- this option not implemented\n", 588 program_name); 589 xexit (1); 590 } 591 } 592 593 END_PROGRESS (program_name); 594 595 xexit (0); 596 return 0; 597} 598 599bfd * 600open_inarch (archive_filename, file) 601 const char *archive_filename; 602 const char *file; 603{ 604 const char *target; 605 bfd **last_one; 606 bfd *next_one; 607 struct stat sbuf; 608 bfd *arch; 609 char **matching; 610 611 bfd_set_error (bfd_error_no_error); 612 613 target = NULL; 614 615 if (stat (archive_filename, &sbuf) != 0) 616 { 617#ifndef __GO32__ 618 619/* KLUDGE ALERT! Temporary fix until I figger why 620 * stat() is wrong ... think it's buried in GO32's IDT 621 * - Jax 622 */ 623 if (errno != ENOENT) 624 bfd_fatal (archive_filename); 625#endif 626 627 if (!operation_alters_arch) 628 { 629 fprintf (stderr, "%s: ", program_name); 630 perror (archive_filename); 631 maybequit (); 632 return NULL; 633 } 634 635 /* Try to figure out the target to use for the archive from the 636 first object on the list. */ 637 if (file != NULL) 638 { 639 bfd *obj; 640 641 obj = bfd_openr (file, NULL); 642 if (obj != NULL) 643 { 644 if (bfd_check_format (obj, bfd_object)) 645 target = bfd_get_target (obj); 646 (void) bfd_close (obj); 647 } 648 } 649 650 /* Create an empty archive. */ 651 arch = bfd_openw (archive_filename, target); 652 if (arch == NULL 653 || ! bfd_set_format (arch, bfd_archive) 654 || ! bfd_close (arch)) 655 bfd_fatal (archive_filename); 656 } 657 658 arch = bfd_openr (archive_filename, target); 659 if (arch == NULL) 660 { 661 bloser: 662 bfd_fatal (archive_filename); 663 } 664 665 if (! bfd_check_format_matches (arch, bfd_archive, &matching)) 666 { 667 bfd_nonfatal (archive_filename); 668 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 669 { 670 list_matching_formats (matching); 671 free (matching); 672 } 673 xexit (1); 674 } 675 676 last_one = &(arch->next); 677 /* Read all the contents right away, regardless. */ 678 for (next_one = bfd_openr_next_archived_file (arch, NULL); 679 next_one; 680 next_one = bfd_openr_next_archived_file (arch, next_one)) 681 { 682 PROGRESS (1); 683 *last_one = next_one; 684 last_one = &next_one->next; 685 } 686 *last_one = (bfd *) NULL; 687 if (bfd_get_error () != bfd_error_no_more_archived_files) 688 goto bloser; 689 return arch; 690} 691 692static void 693print_contents (abfd) 694 bfd *abfd; 695{ 696 int ncopied = 0; 697 char *cbuf = xmalloc (BUFSIZE); 698 struct stat buf; 699 long size; 700 if (bfd_stat_arch_elt (abfd, &buf) != 0) 701 fatal ("internal stat error on %s", bfd_get_filename (abfd)); 702 703 if (verbose) 704 printf ("\n<member %s>\n\n", bfd_get_filename (abfd)); 705 706 bfd_seek (abfd, 0, SEEK_SET); 707 708 size = buf.st_size; 709 while (ncopied < size) 710 { 711 712 int nread; 713 int tocopy = size - ncopied; 714 if (tocopy > BUFSIZE) 715 tocopy = BUFSIZE; 716 717 nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke 718 abstraction! */ 719 if (nread != tocopy) 720 fatal ("%s is not a valid archive", 721 bfd_get_filename (bfd_my_archive (abfd))); 722 fwrite (cbuf, 1, nread, stdout); 723 ncopied += tocopy; 724 } 725 free (cbuf); 726} 727 728/* Extract a member of the archive into its own file. 729 730 We defer opening the new file until after we have read a BUFSIZ chunk of the 731 old one, since we know we have just read the archive header for the old 732 one. Since most members are shorter than BUFSIZ, this means we will read 733 the old header, read the old data, write a new inode for the new file, and 734 write the new data, and be done. This 'optimization' is what comes from 735 sitting next to a bare disk and hearing it every time it seeks. -- Gnu 736 Gilmore */ 737 738void 739extract_file (abfd) 740 bfd *abfd; 741{ 742 FILE *ostream; 743 char *cbuf = xmalloc (BUFSIZE); 744 int nread, tocopy; 745 int ncopied = 0; 746 long size; 747 struct stat buf; 748 if (bfd_stat_arch_elt (abfd, &buf) != 0) 749 fatal ("internal stat error on %s", bfd_get_filename (abfd)); 750 size = buf.st_size; 751 752 if (verbose) 753 printf ("x - %s\n", bfd_get_filename (abfd)); 754 755 bfd_seek (abfd, 0, SEEK_SET); 756 757 ostream = 0; 758 if (size == 0) 759 { 760 /* Seems like an abstraction violation, eh? Well it's OK! */ 761 output_filename = bfd_get_filename (abfd); 762 763 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB); 764 if (!ostream) 765 { 766 perror (bfd_get_filename (abfd)); 767 xexit (1); 768 } 769 770 output_file = ostream; 771 } 772 else 773 while (ncopied < size) 774 { 775 tocopy = size - ncopied; 776 if (tocopy > BUFSIZE) 777 tocopy = BUFSIZE; 778 779 nread = bfd_read (cbuf, 1, tocopy, abfd); 780 if (nread != tocopy) 781 fatal ("%s is not a valid archive", 782 bfd_get_filename (bfd_my_archive (abfd))); 783 784 /* See comment above; this saves disk arm motion */ 785 if (!ostream) 786 { 787 /* Seems like an abstraction violation, eh? Well it's OK! */ 788 output_filename = bfd_get_filename (abfd); 789 790 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB); 791 if (!ostream) 792 { 793 perror (bfd_get_filename (abfd)); 794 xexit (1); 795 } 796 797 output_file = ostream; 798 } 799 fwrite (cbuf, 1, nread, ostream); 800 ncopied += tocopy; 801 } 802 803 fclose (ostream); 804 805 output_file = NULL; 806 output_filename = NULL; 807 808 chmod (bfd_get_filename (abfd), buf.st_mode); 809 810 if (preserve_dates) 811 { 812#ifdef HAVE_GOOD_UTIME_H 813 struct utimbuf tb; 814 tb.actime = buf.st_mtime; 815 tb.modtime = buf.st_mtime; 816 utime (bfd_get_filename (abfd), &tb); /* FIXME check result */ 817#else /* ! HAVE_GOOD_UTIME_H */ 818#ifndef HAVE_UTIMES 819 long tb[2]; 820 tb[0] = buf.st_mtime; 821 tb[1] = buf.st_mtime; 822 utime (bfd_get_filename (abfd), tb); /* FIXME check result */ 823#else /* HAVE_UTIMES */ 824 struct timeval tv[2]; 825 tv[0].tv_sec = buf.st_mtime; 826 tv[0].tv_usec = 0; 827 tv[1].tv_sec = buf.st_mtime; 828 tv[1].tv_usec = 0; 829 utimes (bfd_get_filename (abfd), tv); /* FIXME check result */ 830#endif /* HAVE_UTIMES */ 831#endif /* ! HAVE_GOOD_UTIME_H */ 832 } 833free (cbuf); 834} 835 836#if 0 837 838/* We don't use this anymore. Too many systems expect ar to rebuild 839 the symbol table even when q is used. */ 840 841/* Just do it quickly; don't worry about dups, armap, or anything like that */ 842 843static void 844do_quick_append (archive_filename, files_to_append) 845 const char *archive_filename; 846 char **files_to_append; 847{ 848 FILE *ofile, *ifile; 849 char *buf = xmalloc (BUFSIZE); 850 long tocopy, thistime; 851 bfd *temp; 852 struct stat sbuf; 853 boolean newfile = false; 854 bfd_set_error (bfd_error_no_error); 855 856 if (stat (archive_filename, &sbuf) != 0) 857 { 858 859#ifndef __GO32__ 860 861/* KLUDGE ALERT! Temporary fix until I figger why 862 * stat() is wrong ... think it's buried in GO32's IDT 863 * - Jax 864 */ 865 866 if (errno != ENOENT) 867 bfd_fatal (archive_filename); 868#endif 869 870 newfile = true; 871 } 872 873 ofile = fopen (archive_filename, FOPEN_AUB); 874 if (ofile == NULL) 875 { 876 perror (program_name); 877 xexit (1); 878 } 879 880 temp = bfd_openr (archive_filename, NULL); 881 if (temp == NULL) 882 { 883 bfd_fatal (archive_filename); 884 } 885 if (newfile == false) 886 { 887 if (bfd_check_format (temp, bfd_archive) != true) 888 fatal ("%s is not an archive", archive_filename); 889 } 890 else 891 { 892 fwrite (ARMAG, 1, SARMAG, ofile); 893 if (!silent_create) 894 fprintf (stderr, "%s: creating %s\n", 895 program_name, archive_filename); 896 } 897 898 if (ar_truncate) 899 temp->flags |= BFD_TRADITIONAL_FORMAT; 900 901 /* assume it's an achive, go straight to the end, sans $200 */ 902 fseek (ofile, 0, 2); 903 904 for (; files_to_append && *files_to_append; ++files_to_append) 905 { 906 struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append); 907 if (hdr == NULL) 908 { 909 bfd_fatal (*files_to_append); 910 } 911 912 BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr)); 913 914 ifile = fopen (*files_to_append, FOPEN_RB); 915 if (ifile == NULL) 916 { 917 bfd_nonfatal (*files_to_append); 918 } 919 920 if (stat (*files_to_append, &sbuf) != 0) 921 { 922 bfd_nonfatal (*files_to_append); 923 } 924 925 tocopy = sbuf.st_size; 926 927 /* XXX should do error-checking! */ 928 fwrite (hdr, 1, sizeof (struct ar_hdr), ofile); 929 930 while (tocopy > 0) 931 { 932 thistime = tocopy; 933 if (thistime > BUFSIZE) 934 thistime = BUFSIZE; 935 fread (buf, 1, thistime, ifile); 936 fwrite (buf, 1, thistime, ofile); 937 tocopy -= thistime; 938 } 939 fclose (ifile); 940 if ((sbuf.st_size % 2) == 1) 941 putc ('\012', ofile); 942 } 943 fclose (ofile); 944 bfd_close (temp); 945 free (buf); 946} 947 948#endif /* 0 */ 949 950static void 951write_archive (iarch) 952 bfd *iarch; 953{ 954 bfd *obfd; 955 char *old_name, *new_name; 956 bfd *contents_head = iarch->next; 957 958 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1); 959 strcpy (old_name, bfd_get_filename (iarch)); 960 new_name = make_tempname (old_name); 961 962 output_filename = new_name; 963 964 obfd = bfd_openw (new_name, bfd_get_target (iarch)); 965 966 if (obfd == NULL) 967 bfd_fatal (old_name); 968 969 output_bfd = obfd; 970 971 bfd_set_format (obfd, bfd_archive); 972 973 /* Request writing the archive symbol table unless we've 974 been explicitly requested not to. */ 975 obfd->has_armap = write_armap >= 0; 976 977 if (ar_truncate) 978 { 979 /* This should really use bfd_set_file_flags, but that rejects 980 archives. */ 981 obfd->flags |= BFD_TRADITIONAL_FORMAT; 982 } 983 984 if (bfd_set_archive_head (obfd, contents_head) != true) 985 bfd_fatal (old_name); 986 987 if (!bfd_close (obfd)) 988 bfd_fatal (old_name); 989 990 output_bfd = NULL; 991 output_filename = NULL; 992 993 /* We don't care if this fails; we might be creating the archive. */ 994 bfd_close (iarch); 995 unlink (old_name); 996 997 if (rename (new_name, old_name) != 0) 998 bfd_fatal (old_name); 999} 1000 1001/* Return a pointer to the pointer to the entry which should be rplacd'd 1002 into when altering. DEFAULT_POS should be how to interpret pos_default, 1003 and should be a pos value. */ 1004 1005static bfd ** 1006get_pos_bfd (contents, default_pos) 1007 bfd **contents; 1008 enum pos default_pos; 1009{ 1010 bfd **after_bfd = contents; 1011 enum pos realpos = (postype == pos_default ? default_pos : postype); 1012 1013 if (realpos == pos_end) 1014 { 1015 while (*after_bfd) 1016 after_bfd = &((*after_bfd)->next); 1017 } 1018 else 1019 { 1020 for (; *after_bfd; after_bfd = &(*after_bfd)->next) 1021 if (!strcmp ((*after_bfd)->filename, posname)) 1022 { 1023 if (realpos == pos_after) 1024 after_bfd = &(*after_bfd)->next; 1025 break; 1026 } 1027 } 1028 return after_bfd; 1029} 1030 1031static void 1032delete_members (arch, files_to_delete) 1033 bfd *arch; 1034 char **files_to_delete; 1035{ 1036 bfd **current_ptr_ptr; 1037 boolean found; 1038 boolean something_changed = false; 1039 for (; *files_to_delete != NULL; ++files_to_delete) 1040 { 1041 /* In a.out systems, the armap is optional. It's also called 1042 __.SYMDEF. So if the user asked to delete it, we should remember 1043 that fact. This isn't quite right for COFF systems (where 1044 __.SYMDEF might be regular member), but it's very unlikely 1045 to be a problem. FIXME */ 1046 1047 if (!strcmp (*files_to_delete, "__.SYMDEF")) 1048 { 1049 arch->has_armap = false; 1050 write_armap = -1; 1051 continue; 1052 } 1053 1054 found = false; 1055 current_ptr_ptr = &(arch->next); 1056 while (*current_ptr_ptr) 1057 { 1058 if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0) 1059 { 1060 found = true; 1061 something_changed = true; 1062 if (verbose) 1063 printf ("d - %s\n", 1064 *files_to_delete); 1065 *current_ptr_ptr = ((*current_ptr_ptr)->next); 1066 goto next_file; 1067 } 1068 else 1069 { 1070 current_ptr_ptr = &((*current_ptr_ptr)->next); 1071 } 1072 } 1073 1074 if (verbose && found == false) 1075 { 1076 printf ("No member named `%s'\n", *files_to_delete); 1077 } 1078 next_file: 1079 ; 1080 } 1081 1082 if (something_changed == true) 1083 { 1084 write_archive (arch); 1085 } 1086} 1087 1088 1089/* Reposition existing members within an archive */ 1090 1091static void 1092move_members (arch, files_to_move) 1093 bfd *arch; 1094 char **files_to_move; 1095{ 1096 bfd **after_bfd; /* New entries go after this one */ 1097 bfd **current_ptr_ptr; /* cdr pointer into contents */ 1098 1099 for (; *files_to_move; ++files_to_move) 1100 { 1101 current_ptr_ptr = &(arch->next); 1102 while (*current_ptr_ptr) 1103 { 1104 bfd *current_ptr = *current_ptr_ptr; 1105 if (strcmp (normalize (*files_to_move, arch), 1106 current_ptr->filename) == 0) 1107 { 1108 /* Move this file to the end of the list - first cut from 1109 where it is. */ 1110 bfd *link; 1111 *current_ptr_ptr = current_ptr->next; 1112 1113 /* Now glue to end */ 1114 after_bfd = get_pos_bfd (&arch->next, pos_end); 1115 link = *after_bfd; 1116 *after_bfd = current_ptr; 1117 current_ptr->next = link; 1118 1119 if (verbose) 1120 printf ("m - %s\n", *files_to_move); 1121 1122 goto next_file; 1123 } 1124 1125 current_ptr_ptr = &((*current_ptr_ptr)->next); 1126 } 1127 fprintf (stderr, "%s: no entry %s in archive %s!\n", 1128 program_name, *files_to_move, arch->filename); 1129 xexit (1); 1130 next_file:; 1131 } 1132 1133 write_archive (arch); 1134} 1135 1136/* Ought to default to replacing in place, but this is existing practice! */ 1137 1138static void 1139replace_members (arch, files_to_move, quick) 1140 bfd *arch; 1141 char **files_to_move; 1142 boolean quick; 1143{ 1144 boolean changed = false; 1145 bfd **after_bfd; /* New entries go after this one */ 1146 bfd *current; 1147 bfd **current_ptr; 1148 bfd *temp; 1149 1150 while (files_to_move && *files_to_move) 1151 { 1152 if (! quick) 1153 { 1154 current_ptr = &arch->next; 1155 while (*current_ptr) 1156 { 1157 current = *current_ptr; 1158 1159 /* For compatibility with existing ar programs, we 1160 permit the same file to be added multiple times. */ 1161 if (strcmp (normalize (*files_to_move, arch), 1162 normalize (current->filename, arch)) == 0 1163 && current->arelt_data != NULL) 1164 { 1165 if (newer_only) 1166 { 1167 struct stat fsbuf, asbuf; 1168 1169 if (stat (*files_to_move, &fsbuf) != 0) 1170 { 1171 if (errno != ENOENT) 1172 bfd_fatal (*files_to_move); 1173 goto next_file; 1174 } 1175 if (bfd_stat_arch_elt (current, &asbuf) != 0) 1176 fatal ("internal stat error on %s", current->filename); 1177 1178 if (fsbuf.st_mtime <= asbuf.st_mtime) 1179 goto next_file; 1180 } 1181 1182 /* snip out this entry from the chain */ 1183 *current_ptr = current->next; 1184 1185 after_bfd = get_pos_bfd (&arch->next, pos_end); 1186 temp = *after_bfd; 1187 *after_bfd = bfd_openr (*files_to_move, NULL); 1188 if (*after_bfd == (bfd *) NULL) 1189 { 1190 bfd_fatal (*files_to_move); 1191 } 1192 (*after_bfd)->next = temp; 1193 1194 if (verbose) 1195 { 1196 printf ("r - %s\n", *files_to_move); 1197 } 1198 1199 changed = true; 1200 1201 goto next_file; 1202 } 1203 current_ptr = &(current->next); 1204 } 1205 } 1206 1207 /* Add to the end of the archive. */ 1208 1209 after_bfd = get_pos_bfd (&arch->next, pos_end); 1210 temp = *after_bfd; 1211 *after_bfd = bfd_openr (*files_to_move, NULL); 1212 if (*after_bfd == (bfd *) NULL) 1213 { 1214 bfd_fatal (*files_to_move); 1215 } 1216 if (verbose) 1217 { 1218 printf ("a - %s\n", *files_to_move); 1219 } 1220 1221 (*after_bfd)->next = temp; 1222 1223 changed = true; 1224 1225 next_file:; 1226 1227 files_to_move++; 1228 } 1229 1230 if (changed) 1231 write_archive (arch); 1232} 1233 1234static void 1235ranlib_only (archname) 1236 const char *archname; 1237{ 1238 bfd *arch; 1239 1240 write_armap = 1; 1241 arch = open_inarch (archname, (char *) NULL); 1242 if (arch == NULL) 1243 xexit (1); 1244 write_archive (arch); 1245} 1246 1247/* Update the timestamp of the symbol map of an archive. */ 1248 1249static void 1250ranlib_touch (archname) 1251 const char *archname; 1252{ 1253#ifdef __GO32__ 1254 /* I don't think updating works on go32. */ 1255 ranlib_only (archname); 1256#else 1257 int f; 1258 bfd *arch; 1259 char **matching; 1260 1261 f = open (archname, O_RDWR, 0); 1262 if (f < 0) 1263 { 1264 bfd_set_error (bfd_error_system_call); 1265 bfd_fatal (archname); 1266 } 1267 1268 arch = bfd_fdopenr (archname, (const char *) NULL, f); 1269 if (arch == NULL) 1270 bfd_fatal (archname); 1271 if (! bfd_check_format_matches (arch, bfd_archive, &matching)) 1272 { 1273 bfd_nonfatal (archname); 1274 if (bfd_get_error () == bfd_error_file_ambiguously_recognized) 1275 { 1276 list_matching_formats (matching); 1277 free (matching); 1278 } 1279 xexit (1); 1280 } 1281 1282 if (! bfd_has_map (arch)) 1283 fatal ("%s: no archive map to update", archname); 1284 1285 bfd_update_armap_timestamp (arch); 1286 1287 if (! bfd_close (arch)) 1288 bfd_fatal (archname); 1289#endif 1290} 1291 1292/* Things which are interesting to map over all or some of the files: */ 1293 1294static void 1295print_descr (abfd) 1296 bfd *abfd; 1297{ 1298 print_arelt_descr (stdout, abfd, verbose); 1299} 1300