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