Replace 'arch' field with 'mach'.
[binutils.git] / binutils / ar.c
blob92d9b35bfbda9ddea5bfb4101538d9e1875a45da
1 /* ar.c - Archive modify and extract.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
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.
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.
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. */
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 consistant.
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 <sys/stat.h>
39 #ifdef __GO32___
40 #define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
41 #else
42 #define EXT_NAME_LEN 6 /* ditto for *NIX */
43 #endif
45 /* We need to open files in binary modes on system where that makes a
46 difference. */
47 #ifndef O_BINARY
48 #define O_BINARY 0
49 #endif
51 #define BUFSIZE 8192
53 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
55 struct ar_hdr *
56 bfd_special_undocumented_glue PARAMS ((bfd * abfd, const char *filename));
58 /* Static declarations */
60 static void
61 mri_emul PARAMS ((void));
63 static const char *
64 normalize PARAMS ((const char *, bfd *));
66 static void
67 remove_output PARAMS ((void));
69 static void
70 map_over_members PARAMS ((bfd *, void (*)(bfd *), char **, int));
72 static void
73 print_contents PARAMS ((bfd * member));
75 static void
76 delete_members PARAMS ((bfd *, char **files_to_delete));
78 #if 0
79 static void
80 do_quick_append PARAMS ((const char *archive_filename,
81 char **files_to_append));
82 #endif
84 static void
85 move_members PARAMS ((bfd *, char **files_to_move));
87 static void
88 replace_members PARAMS ((bfd *, char **files_to_replace, boolean quick));
90 static void
91 print_descr PARAMS ((bfd * abfd));
93 static void
94 write_archive PARAMS ((bfd *));
96 static void
97 ranlib_only PARAMS ((const char *archname));
99 static void
100 ranlib_touch PARAMS ((const char *archname));
102 static void
103 usage PARAMS ((int));
105 /** Globals and flags */
107 int mri_mode;
109 /* This flag distinguishes between ar and ranlib:
110 1 means this is 'ranlib'; 0 means this is 'ar'.
111 -1 means if we should use argv[0] to decide. */
112 extern int is_ranlib;
114 /* Nonzero means don't warn about creating the archive file if necessary. */
115 int silent_create = 0;
117 /* Nonzero means describe each action performed. */
118 int verbose = 0;
120 /* Nonzero means preserve dates of members when extracting them. */
121 int preserve_dates = 0;
123 /* Nonzero means don't replace existing members whose dates are more recent
124 than the corresponding files. */
125 int newer_only = 0;
127 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
128 member). -1 means we've been explicitly asked to not write a symbol table;
129 +1 means we've been explictly asked to write it;
130 0 is the default.
131 Traditionally, the default in BSD has been to not write the table.
132 However, for POSIX.2 compliance the default is now to write a symbol table
133 if any of the members are object files. */
134 int write_armap = 0;
136 /* Nonzero means it's the name of an existing member; position new or moved
137 files with respect to this one. */
138 char *posname = NULL;
140 /* Sez how to use `posname': pos_before means position before that member.
141 pos_after means position after that member. pos_end means always at end.
142 pos_default means default appropriately. For the latter two, `posname'
143 should also be zero. */
144 enum pos
146 pos_default, pos_before, pos_after, pos_end
147 } postype = pos_default;
149 static bfd **
150 get_pos_bfd PARAMS ((bfd **, enum pos, const char *));
152 /* For extract/delete only. If COUNTED_NAME_MODE is true, we only
153 extract the COUNTED_NAME_COUNTER instance of that name. */
154 static boolean counted_name_mode = 0;
155 static int counted_name_counter = 0;
157 /* Whether to truncate names of files stored in the archive. */
158 static boolean ar_truncate = false;
160 /* Whether to use a full file name match when searching an archive.
161 This is convenient for archives created by the Microsoft lib
162 program. */
163 static boolean full_pathname = false;
165 int interactive = 0;
167 static void
168 mri_emul ()
170 interactive = isatty (fileno (stdin));
171 yyparse ();
174 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
175 COUNT is the length of the FILES chain; FUNCTION is called on each entry
176 whose name matches one in FILES. */
178 static void
179 map_over_members (arch, function, files, count)
180 bfd *arch;
181 void (*function) PARAMS ((bfd *));
182 char **files;
183 int count;
185 bfd *head;
186 int match_count;
188 if (count == 0)
190 for (head = arch->next; head; head = head->next)
192 PROGRESS (1);
193 function (head);
195 return;
198 /* This may appear to be a baroque way of accomplishing what we want.
199 However we have to iterate over the filenames in order to notice where
200 a filename is requested but does not exist in the archive. Ditto
201 mapping over each file each time -- we want to hack multiple
202 references. */
204 for (; count > 0; files++, count--)
206 boolean found = false;
208 match_count = 0;
209 for (head = arch->next; head; head = head->next)
211 PROGRESS (1);
212 if (head->filename == NULL)
214 /* Some archive formats don't get the filenames filled in
215 until the elements are opened. */
216 struct stat buf;
217 bfd_stat_arch_elt (head, &buf);
219 if ((head->filename != NULL) &&
220 (!FILENAME_CMP (normalize (*files, arch), head->filename)))
222 ++match_count;
223 if (counted_name_mode
224 && match_count != counted_name_counter)
226 /* Counting, and didn't match on count; go on to the
227 next one. */
228 continue;
231 found = true;
232 function (head);
235 if (!found)
236 /* xgettext:c-format */
237 fprintf (stderr, _("no entry %s in archive\n"), *files);
241 boolean operation_alters_arch = false;
243 static void
244 usage (help)
245 int help;
247 FILE *s;
249 s = help ? stdout : stderr;
251 if (! is_ranlib)
253 /* xgettext:c-format */
254 fprintf (s, _("Usage: %s [-X32_64] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
255 program_name);
256 /* xgettext:c-format */
257 fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
258 fprintf (s, _(" commands:\n"));
259 fprintf (s, _(" d - delete file(s) from the archive\n"));
260 fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
261 fprintf (s, _(" p - print file(s) found in the archive\n"));
262 fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
263 fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
264 fprintf (s, _(" t - display contents of archive\n"));
265 fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
266 fprintf (s, _(" command specific modifiers:\n"));
267 fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
268 fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
269 fprintf (s, _(" [N] - use instance [count] of name\n"));
270 fprintf (s, _(" [f] - truncate inserted file names\n"));
271 fprintf (s, _(" [P] - use full path names when matching\n"));
272 fprintf (s, _(" [o] - preserve original dates\n"));
273 fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
274 fprintf (s, _(" generic modifiers:\n"));
275 fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
276 fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
277 fprintf (s, _(" [S] - do not build a symbol table\n"));
278 fprintf (s, _(" [v] - be verbose\n"));
279 fprintf (s, _(" [V] - display the version number\n"));
280 fprintf (s, _(" [-X32_64] - (ignored)\n"));
282 else
284 /* xgettext:c-format */
285 fprintf (s, _("Usage: %s [options] archive\n"), program_name);
286 fprintf (s, _(" Generate an index to speed access to archives\n"));
287 fprintf (s, _(" The options are:\n\
288 -h --help Print this help message\n\
289 -V --version Print version information\n"));
292 list_supported_targets (program_name, stderr);
294 if (help)
295 fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
297 xexit (help ? 0 : 1);
300 /* Normalize a file name specified on the command line into a file
301 name which we will use in an archive. */
303 static const char *
304 normalize (file, abfd)
305 const char *file;
306 bfd *abfd;
308 const char *filename;
310 if (full_pathname)
311 return file;
313 filename = strrchr (file, '/');
314 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
316 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
317 char *bslash = strrchr (file, '\\');
318 if (filename == NULL || (bslash != NULL && bslash > filename))
319 filename = bslash;
320 if (filename == NULL && file[0] != '\0' && file[1] == ':')
321 filename = file + 1;
323 #endif
324 if (filename != (char *) NULL)
325 filename++;
326 else
327 filename = file;
329 if (ar_truncate
330 && abfd != NULL
331 && strlen (filename) > abfd->xvec->ar_max_namelen)
333 char *s;
335 /* Space leak. */
336 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
337 memcpy (s, filename, abfd->xvec->ar_max_namelen);
338 s[abfd->xvec->ar_max_namelen] = '\0';
339 filename = s;
342 return filename;
345 /* Remove any output file. This is only called via xatexit. */
347 static const char *output_filename = NULL;
348 static FILE *output_file = NULL;
349 static bfd *output_bfd = NULL;
351 static void
352 remove_output ()
354 if (output_filename != NULL)
356 if (output_bfd != NULL && output_bfd->iostream != NULL)
357 fclose ((FILE *) (output_bfd->iostream));
358 if (output_file != NULL)
359 fclose (output_file);
360 unlink (output_filename);
364 /* The option parsing should be in its own function.
365 It will be when I have getopt working. */
367 int main PARAMS ((int, char **));
370 main (argc, argv)
371 int argc;
372 char **argv;
374 char *arg_ptr;
375 char c;
376 enum
378 none = 0, delete, replace, print_table,
379 print_files, extract, move, quick_append
380 } operation = none;
381 int arg_index;
382 char **files;
383 int file_count;
384 char *inarch_filename;
385 int show_version;
387 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
388 setlocale (LC_MESSAGES, "");
389 #endif
390 #if defined (HAVE_SETLOCALE)
391 setlocale (LC_CTYPE, "");
392 #endif
393 bindtextdomain (PACKAGE, LOCALEDIR);
394 textdomain (PACKAGE);
396 program_name = argv[0];
397 xmalloc_set_program_name (program_name);
399 if (is_ranlib < 0)
401 char *temp;
403 temp = strrchr (program_name, '/');
404 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
406 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
407 char *bslash = strrchr (program_name, '\\');
408 if (temp == NULL || (bslash != NULL && bslash > temp))
409 temp = bslash;
410 if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
411 temp = program_name + 1;
413 #endif
414 if (temp == NULL)
415 temp = program_name;
416 else
417 ++temp;
418 if (strlen (temp) >= 6
419 && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
420 is_ranlib = 1;
421 else
422 is_ranlib = 0;
425 if (argc > 1 && argv[1][0] == '-')
427 if (strcmp (argv[1], "--help") == 0)
428 usage (1);
429 else if (strcmp (argv[1], "--version") == 0)
431 if (is_ranlib)
432 print_version ("ranlib");
433 else
434 print_version ("ar");
438 START_PROGRESS (program_name, 0);
440 bfd_init ();
441 set_default_bfd_target ();
443 show_version = 0;
445 xatexit (remove_output);
447 /* Ignored for (partial) AIX compatibility. On AIX,
448 the -X option can be used to ignore certain kinds
449 of object files in the archive (the 64-bit objects
450 or the 32-bit objects). GNU ar always looks at all
451 kinds of objects in an archive. */
452 while (argc > 1 && strcmp (argv[1], "-X32_64") == 0)
454 argv++;
455 argc--;
458 if (is_ranlib)
460 boolean touch = false;
462 if (argc < 2
463 || strcmp (argv[1], "--help") == 0
464 || strcmp (argv[1], "-h") == 0
465 || strcmp (argv[1], "-H") == 0)
466 usage (0);
467 if (strcmp (argv[1], "-V") == 0
468 || strcmp (argv[1], "-v") == 0
469 || strncmp (argv[1], "--v", 3) == 0)
470 print_version ("ranlib");
471 arg_index = 1;
472 if (strcmp (argv[1], "-t") == 0)
474 ++arg_index;
475 touch = true;
477 while (arg_index < argc)
479 if (! touch)
480 ranlib_only (argv[arg_index]);
481 else
482 ranlib_touch (argv[arg_index]);
483 ++arg_index;
485 xexit (0);
488 if (argc == 2 && strcmp (argv[1], "-M") == 0)
490 mri_emul ();
491 xexit (0);
494 if (argc < 2)
495 usage (0);
497 arg_ptr = argv[1];
499 if (*arg_ptr == '-')
500 ++arg_ptr; /* compatibility */
502 while ((c = *arg_ptr++) != '\0')
504 switch (c)
506 case 'd':
507 case 'm':
508 case 'p':
509 case 'q':
510 case 'r':
511 case 't':
512 case 'x':
513 if (operation != none)
514 fatal (_("two different operation options specified"));
515 switch (c)
517 case 'd':
518 operation = delete;
519 operation_alters_arch = true;
520 break;
521 case 'm':
522 operation = move;
523 operation_alters_arch = true;
524 break;
525 case 'p':
526 operation = print_files;
527 break;
528 case 'q':
529 operation = quick_append;
530 operation_alters_arch = true;
531 break;
532 case 'r':
533 operation = replace;
534 operation_alters_arch = true;
535 break;
536 case 't':
537 operation = print_table;
538 break;
539 case 'x':
540 operation = extract;
541 break;
543 case 'l':
544 break;
545 case 'c':
546 silent_create = 1;
547 break;
548 case 'o':
549 preserve_dates = 1;
550 break;
551 case 'V':
552 show_version = true;
553 break;
554 case 's':
555 write_armap = 1;
556 break;
557 case 'S':
558 write_armap = -1;
559 break;
560 case 'u':
561 newer_only = 1;
562 break;
563 case 'v':
564 verbose = 1;
565 break;
566 case 'a':
567 postype = pos_after;
568 break;
569 case 'b':
570 postype = pos_before;
571 break;
572 case 'i':
573 postype = pos_before;
574 break;
575 case 'M':
576 mri_mode = 1;
577 break;
578 case 'N':
579 counted_name_mode = true;
580 break;
581 case 'f':
582 ar_truncate = true;
583 break;
584 case 'P':
585 full_pathname = true;
586 break;
587 default:
588 /* xgettext:c-format */
589 non_fatal (_("illegal option -- %c"), c);
590 usage (0);
594 if (show_version)
595 print_version ("ar");
597 if (argc < 3)
598 usage (0);
600 if (mri_mode)
602 mri_emul ();
604 else
606 bfd *arch;
608 /* We can't write an armap when using ar q, so just do ar r
609 instead. */
610 if (operation == quick_append && write_armap)
611 operation = replace;
613 if ((operation == none || operation == print_table)
614 && write_armap == 1)
616 ranlib_only (argv[2]);
617 xexit (0);
620 if (operation == none)
621 fatal (_("no operation specified"));
623 if (newer_only && operation != replace)
624 fatal (_("`u' is only meaningful with the `r' option."));
626 arg_index = 2;
628 if (postype != pos_default)
629 posname = argv[arg_index++];
631 if (counted_name_mode)
633 if (operation != extract && operation != delete)
634 fatal (_("`N' is only meaningful with the `x' and `d' options."));
635 counted_name_counter = atoi (argv[arg_index++]);
636 if (counted_name_counter <= 0)
637 fatal (_("Value for `N' must be positive."));
640 inarch_filename = argv[arg_index++];
642 files = arg_index < argc ? argv + arg_index : NULL;
643 file_count = argc - arg_index;
645 #if 0
646 /* We don't use do_quick_append any more. Too many systems
647 expect ar to always rebuild the symbol table even when q is
648 used. */
650 /* We can't do a quick append if we need to construct an
651 extended name table, because do_quick_append won't be able to
652 rebuild the name table. Unfortunately, at this point we
653 don't actually know the maximum name length permitted by this
654 object file format. So, we guess. FIXME. */
655 if (operation == quick_append && ! ar_truncate)
657 char **chk;
659 for (chk = files; chk != NULL && *chk != '\0'; chk++)
661 if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
663 operation = replace;
664 break;
669 if (operation == quick_append)
671 /* Note that quick appending to a non-existent archive creates it,
672 even if there are no files to append. */
673 do_quick_append (inarch_filename, files);
674 xexit (0);
676 #endif
678 arch = open_inarch (inarch_filename,
679 files == NULL ? (char *) NULL : files[0]);
681 switch (operation)
683 case print_table:
684 map_over_members (arch, print_descr, files, file_count);
685 break;
687 case print_files:
688 map_over_members (arch, print_contents, files, file_count);
689 break;
691 case extract:
692 map_over_members (arch, extract_file, files, file_count);
693 break;
695 case delete:
696 if (files != NULL)
697 delete_members (arch, files);
698 else
699 output_filename = NULL;
700 break;
702 case move:
703 if (files != NULL)
704 move_members (arch, files);
705 else
706 output_filename = NULL;
707 break;
709 case replace:
710 case quick_append:
711 if (files != NULL || write_armap > 0)
712 replace_members (arch, files, operation == quick_append);
713 else
714 output_filename = NULL;
715 break;
717 /* Shouldn't happen! */
718 default:
719 /* xgettext:c-format */
720 fatal (_("internal error -- this option not implemented"));
724 END_PROGRESS (program_name);
726 xexit (0);
727 return 0;
730 bfd *
731 open_inarch (archive_filename, file)
732 const char *archive_filename;
733 const char *file;
735 const char *target;
736 bfd **last_one;
737 bfd *next_one;
738 struct stat sbuf;
739 bfd *arch;
740 char **matching;
742 bfd_set_error (bfd_error_no_error);
744 target = NULL;
746 if (stat (archive_filename, &sbuf) != 0)
748 #if !defined(__GO32__) || defined(__DJGPP__)
750 /* FIXME: I don't understand why this fragment was ifndef'ed
751 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
752 stat() works just fine in v2.x, so I think this should be
753 removed. For now, I enable it for DJGPP v2. -- EZ. */
755 /* KLUDGE ALERT! Temporary fix until I figger why
756 stat() is wrong ... think it's buried in GO32's IDT - Jax */
757 if (errno != ENOENT)
758 bfd_fatal (archive_filename);
759 #endif
761 if (!operation_alters_arch)
763 fprintf (stderr, "%s: ", program_name);
764 perror (archive_filename);
765 maybequit ();
766 return NULL;
769 /* Try to figure out the target to use for the archive from the
770 first object on the list. */
771 if (file != NULL)
773 bfd *obj;
775 obj = bfd_openr (file, NULL);
776 if (obj != NULL)
778 if (bfd_check_format (obj, bfd_object))
779 target = bfd_get_target (obj);
780 (void) bfd_close (obj);
784 /* Create an empty archive. */
785 arch = bfd_openw (archive_filename, target);
786 if (arch == NULL
787 || ! bfd_set_format (arch, bfd_archive)
788 || ! bfd_close (arch))
789 bfd_fatal (archive_filename);
791 /* If we die creating a new archive, don't leave it around. */
792 output_filename = archive_filename;
795 arch = bfd_openr (archive_filename, target);
796 if (arch == NULL)
798 bloser:
799 bfd_fatal (archive_filename);
802 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
804 bfd_nonfatal (archive_filename);
805 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
807 list_matching_formats (matching);
808 free (matching);
810 xexit (1);
813 last_one = &(arch->next);
814 /* Read all the contents right away, regardless. */
815 for (next_one = bfd_openr_next_archived_file (arch, NULL);
816 next_one;
817 next_one = bfd_openr_next_archived_file (arch, next_one))
819 PROGRESS (1);
820 *last_one = next_one;
821 last_one = &next_one->next;
823 *last_one = (bfd *) NULL;
824 if (bfd_get_error () != bfd_error_no_more_archived_files)
825 goto bloser;
826 return arch;
829 static void
830 print_contents (abfd)
831 bfd *abfd;
833 int ncopied = 0;
834 char *cbuf = xmalloc (BUFSIZE);
835 struct stat buf;
836 long size;
837 if (bfd_stat_arch_elt (abfd, &buf) != 0)
838 /* xgettext:c-format */
839 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
841 if (verbose)
842 /* xgettext:c-format */
843 printf (_("\n<member %s>\n\n"), bfd_get_filename (abfd));
845 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
847 size = buf.st_size;
848 while (ncopied < size)
851 int nread;
852 int tocopy = size - ncopied;
853 if (tocopy > BUFSIZE)
854 tocopy = BUFSIZE;
856 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
857 if (nread != tocopy)
858 /* xgettext:c-format */
859 fatal (_("%s is not a valid archive"),
860 bfd_get_filename (bfd_my_archive (abfd)));
861 fwrite (cbuf, 1, nread, stdout);
862 ncopied += tocopy;
864 free (cbuf);
867 /* Extract a member of the archive into its own file.
869 We defer opening the new file until after we have read a BUFSIZ chunk of the
870 old one, since we know we have just read the archive header for the old
871 one. Since most members are shorter than BUFSIZ, this means we will read
872 the old header, read the old data, write a new inode for the new file, and
873 write the new data, and be done. This 'optimization' is what comes from
874 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
875 Gilmore */
877 void
878 extract_file (abfd)
879 bfd *abfd;
881 FILE *ostream;
882 char *cbuf = xmalloc (BUFSIZE);
883 int nread, tocopy;
884 long ncopied = 0;
885 long size;
886 struct stat buf;
888 if (bfd_stat_arch_elt (abfd, &buf) != 0)
889 /* xgettext:c-format */
890 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
891 size = buf.st_size;
893 if (size < 0)
894 /* xgettext:c-format */
895 fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
897 if (verbose)
898 printf ("x - %s\n", bfd_get_filename (abfd));
900 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
902 ostream = NULL;
903 if (size == 0)
905 /* Seems like an abstraction violation, eh? Well it's OK! */
906 output_filename = bfd_get_filename (abfd);
908 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
909 if (ostream == NULL)
911 perror (bfd_get_filename (abfd));
912 xexit (1);
915 output_file = ostream;
917 else
918 while (ncopied < size)
920 tocopy = size - ncopied;
921 if (tocopy > BUFSIZE)
922 tocopy = BUFSIZE;
924 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
925 if (nread != tocopy)
926 /* xgettext:c-format */
927 fatal (_("%s is not a valid archive"),
928 bfd_get_filename (bfd_my_archive (abfd)));
930 /* See comment above; this saves disk arm motion */
931 if (ostream == NULL)
933 /* Seems like an abstraction violation, eh? Well it's OK! */
934 output_filename = bfd_get_filename (abfd);
936 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
937 if (ostream == NULL)
939 perror (bfd_get_filename (abfd));
940 xexit (1);
943 output_file = ostream;
945 fwrite (cbuf, 1, nread, ostream);
946 ncopied += tocopy;
949 if (ostream != NULL)
950 fclose (ostream);
952 output_file = NULL;
953 output_filename = NULL;
955 chmod (bfd_get_filename (abfd), buf.st_mode);
957 if (preserve_dates)
958 set_times (bfd_get_filename (abfd), &buf);
960 free (cbuf);
963 #if 0
965 /* We don't use this anymore. Too many systems expect ar to rebuild
966 the symbol table even when q is used. */
968 /* Just do it quickly; don't worry about dups, armap, or anything like that */
970 static void
971 do_quick_append (archive_filename, files_to_append)
972 const char *archive_filename;
973 char **files_to_append;
975 FILE *ofile, *ifile;
976 char *buf = xmalloc (BUFSIZE);
977 long tocopy, thistime;
978 bfd *temp;
979 struct stat sbuf;
980 boolean newfile = false;
981 bfd_set_error (bfd_error_no_error);
983 if (stat (archive_filename, &sbuf) != 0)
986 #if !defined(__GO32__) || defined(__DJGPP__)
988 /* FIXME: I don't understand why this fragment was ifndef'ed
989 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
990 stat() works just fine in v2.x, so I think this should be
991 removed. For now, I enable it for DJGPP v2.
993 (And yes, I know this is all unused, but somebody, someday,
994 might wish to resurrect this again... -- EZ. */
996 /* KLUDGE ALERT! Temporary fix until I figger why
997 stat() is wrong ... think it's buried in GO32's IDT - Jax */
999 if (errno != ENOENT)
1000 bfd_fatal (archive_filename);
1001 #endif
1003 newfile = true;
1006 ofile = fopen (archive_filename, FOPEN_AUB);
1007 if (ofile == NULL)
1009 perror (program_name);
1010 xexit (1);
1013 temp = bfd_openr (archive_filename, NULL);
1014 if (temp == NULL)
1016 bfd_fatal (archive_filename);
1018 if (newfile == false)
1020 if (bfd_check_format (temp, bfd_archive) != true)
1021 /* xgettext:c-format */
1022 fatal (_("%s is not an archive"), archive_filename);
1024 else
1026 fwrite (ARMAG, 1, SARMAG, ofile);
1027 if (!silent_create)
1028 /* xgettext:c-format */
1029 non_fatal (_("creating %s"), archive_filename);
1032 if (ar_truncate)
1033 temp->flags |= BFD_TRADITIONAL_FORMAT;
1035 /* assume it's an achive, go straight to the end, sans $200 */
1036 fseek (ofile, 0, 2);
1038 for (; files_to_append && *files_to_append; ++files_to_append)
1040 struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
1041 if (hdr == NULL)
1043 bfd_fatal (*files_to_append);
1046 BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
1048 ifile = fopen (*files_to_append, FOPEN_RB);
1049 if (ifile == NULL)
1051 bfd_nonfatal (*files_to_append);
1054 if (stat (*files_to_append, &sbuf) != 0)
1056 bfd_nonfatal (*files_to_append);
1059 tocopy = sbuf.st_size;
1061 /* XXX should do error-checking! */
1062 fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
1064 while (tocopy > 0)
1066 thistime = tocopy;
1067 if (thistime > BUFSIZE)
1068 thistime = BUFSIZE;
1069 fread (buf, 1, thistime, ifile);
1070 fwrite (buf, 1, thistime, ofile);
1071 tocopy -= thistime;
1073 fclose (ifile);
1074 if ((sbuf.st_size % 2) == 1)
1075 putc ('\012', ofile);
1077 fclose (ofile);
1078 bfd_close (temp);
1079 free (buf);
1082 #endif /* 0 */
1084 static void
1085 write_archive (iarch)
1086 bfd *iarch;
1088 bfd *obfd;
1089 char *old_name, *new_name;
1090 bfd *contents_head = iarch->next;
1092 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1093 strcpy (old_name, bfd_get_filename (iarch));
1094 new_name = make_tempname (old_name);
1096 output_filename = new_name;
1098 obfd = bfd_openw (new_name, bfd_get_target (iarch));
1100 if (obfd == NULL)
1101 bfd_fatal (old_name);
1103 output_bfd = obfd;
1105 bfd_set_format (obfd, bfd_archive);
1107 /* Request writing the archive symbol table unless we've
1108 been explicitly requested not to. */
1109 obfd->has_armap = write_armap >= 0;
1111 if (ar_truncate)
1113 /* This should really use bfd_set_file_flags, but that rejects
1114 archives. */
1115 obfd->flags |= BFD_TRADITIONAL_FORMAT;
1118 if (bfd_set_archive_head (obfd, contents_head) != true)
1119 bfd_fatal (old_name);
1121 if (!bfd_close (obfd))
1122 bfd_fatal (old_name);
1124 output_bfd = NULL;
1125 output_filename = NULL;
1127 /* We don't care if this fails; we might be creating the archive. */
1128 bfd_close (iarch);
1130 if (smart_rename (new_name, old_name, 0) != 0)
1131 xexit (1);
1134 /* Return a pointer to the pointer to the entry which should be rplacd'd
1135 into when altering. DEFAULT_POS should be how to interpret pos_default,
1136 and should be a pos value. */
1138 static bfd **
1139 get_pos_bfd (contents, default_pos, default_posname)
1140 bfd **contents;
1141 enum pos default_pos;
1142 const char *default_posname;
1144 bfd **after_bfd = contents;
1145 enum pos realpos;
1146 const char *realposname;
1148 if (postype == pos_default)
1150 realpos = default_pos;
1151 realposname = default_posname;
1153 else
1155 realpos = postype;
1156 realposname = posname;
1159 if (realpos == pos_end)
1161 while (*after_bfd)
1162 after_bfd = &((*after_bfd)->next);
1164 else
1166 for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1167 if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1169 if (realpos == pos_after)
1170 after_bfd = &(*after_bfd)->next;
1171 break;
1174 return after_bfd;
1177 static void
1178 delete_members (arch, files_to_delete)
1179 bfd *arch;
1180 char **files_to_delete;
1182 bfd **current_ptr_ptr;
1183 boolean found;
1184 boolean something_changed = false;
1185 int match_count;
1187 for (; *files_to_delete != NULL; ++files_to_delete)
1189 /* In a.out systems, the armap is optional. It's also called
1190 __.SYMDEF. So if the user asked to delete it, we should remember
1191 that fact. This isn't quite right for COFF systems (where
1192 __.SYMDEF might be regular member), but it's very unlikely
1193 to be a problem. FIXME */
1195 if (!strcmp (*files_to_delete, "__.SYMDEF"))
1197 arch->has_armap = false;
1198 write_armap = -1;
1199 continue;
1202 found = false;
1203 match_count = 0;
1204 current_ptr_ptr = &(arch->next);
1205 while (*current_ptr_ptr)
1207 if (FILENAME_CMP (normalize (*files_to_delete, arch),
1208 (*current_ptr_ptr)->filename) == 0)
1210 ++match_count;
1211 if (counted_name_mode
1212 && match_count != counted_name_counter)
1214 /* Counting, and didn't match on count; go on to the
1215 next one. */
1217 else
1219 found = true;
1220 something_changed = true;
1221 if (verbose)
1222 printf ("d - %s\n",
1223 *files_to_delete);
1224 *current_ptr_ptr = ((*current_ptr_ptr)->next);
1225 goto next_file;
1229 current_ptr_ptr = &((*current_ptr_ptr)->next);
1232 if (verbose && found == false)
1234 /* xgettext:c-format */
1235 printf (_("No member named `%s'\n"), *files_to_delete);
1237 next_file:
1241 if (something_changed == true)
1242 write_archive (arch);
1243 else
1244 output_filename = NULL;
1248 /* Reposition existing members within an archive */
1250 static void
1251 move_members (arch, files_to_move)
1252 bfd *arch;
1253 char **files_to_move;
1255 bfd **after_bfd; /* New entries go after this one */
1256 bfd **current_ptr_ptr; /* cdr pointer into contents */
1258 for (; *files_to_move; ++files_to_move)
1260 current_ptr_ptr = &(arch->next);
1261 while (*current_ptr_ptr)
1263 bfd *current_ptr = *current_ptr_ptr;
1264 if (FILENAME_CMP (normalize (*files_to_move, arch),
1265 current_ptr->filename) == 0)
1267 /* Move this file to the end of the list - first cut from
1268 where it is. */
1269 bfd *link;
1270 *current_ptr_ptr = current_ptr->next;
1272 /* Now glue to end */
1273 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1274 link = *after_bfd;
1275 *after_bfd = current_ptr;
1276 current_ptr->next = link;
1278 if (verbose)
1279 printf ("m - %s\n", *files_to_move);
1281 goto next_file;
1284 current_ptr_ptr = &((*current_ptr_ptr)->next);
1286 /* xgettext:c-format */
1287 fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1289 next_file:;
1292 write_archive (arch);
1295 /* Ought to default to replacing in place, but this is existing practice! */
1297 static void
1298 replace_members (arch, files_to_move, quick)
1299 bfd *arch;
1300 char **files_to_move;
1301 boolean quick;
1303 boolean changed = false;
1304 bfd **after_bfd; /* New entries go after this one */
1305 bfd *current;
1306 bfd **current_ptr;
1307 bfd *temp;
1309 while (files_to_move && *files_to_move)
1311 if (! quick)
1313 current_ptr = &arch->next;
1314 while (*current_ptr)
1316 current = *current_ptr;
1318 /* For compatibility with existing ar programs, we
1319 permit the same file to be added multiple times. */
1320 if (FILENAME_CMP (normalize (*files_to_move, arch),
1321 normalize (current->filename, arch)) == 0
1322 && current->arelt_data != NULL)
1324 if (newer_only)
1326 struct stat fsbuf, asbuf;
1328 if (stat (*files_to_move, &fsbuf) != 0)
1330 if (errno != ENOENT)
1331 bfd_fatal (*files_to_move);
1332 goto next_file;
1334 if (bfd_stat_arch_elt (current, &asbuf) != 0)
1335 /* xgettext:c-format */
1336 fatal (_("internal stat error on %s"), current->filename);
1338 if (fsbuf.st_mtime <= asbuf.st_mtime)
1339 goto next_file;
1342 after_bfd = get_pos_bfd (&arch->next, pos_after,
1343 current->filename);
1344 temp = *after_bfd;
1346 *after_bfd = bfd_openr (*files_to_move, NULL);
1347 if (*after_bfd == (bfd *) NULL)
1349 bfd_fatal (*files_to_move);
1351 (*after_bfd)->next = temp;
1353 /* snip out this entry from the chain */
1354 *current_ptr = (*current_ptr)->next;
1356 if (verbose)
1358 printf ("r - %s\n", *files_to_move);
1361 changed = true;
1363 goto next_file;
1365 current_ptr = &(current->next);
1369 /* Add to the end of the archive. */
1371 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1372 temp = *after_bfd;
1373 *after_bfd = bfd_openr (*files_to_move, NULL);
1374 if (*after_bfd == (bfd *) NULL)
1376 bfd_fatal (*files_to_move);
1378 if (verbose)
1380 printf ("a - %s\n", *files_to_move);
1383 (*after_bfd)->next = temp;
1385 changed = true;
1387 next_file:;
1389 files_to_move++;
1392 if (changed)
1393 write_archive (arch);
1394 else
1395 output_filename = NULL;
1398 static void
1399 ranlib_only (archname)
1400 const char *archname;
1402 bfd *arch;
1404 write_armap = 1;
1405 arch = open_inarch (archname, (char *) NULL);
1406 if (arch == NULL)
1407 xexit (1);
1408 write_archive (arch);
1411 /* Update the timestamp of the symbol map of an archive. */
1413 static void
1414 ranlib_touch (archname)
1415 const char *archname;
1417 #ifdef __GO32__
1418 /* I don't think updating works on go32. */
1419 ranlib_only (archname);
1420 #else
1421 int f;
1422 bfd *arch;
1423 char **matching;
1425 f = open (archname, O_RDWR | O_BINARY, 0);
1426 if (f < 0)
1428 bfd_set_error (bfd_error_system_call);
1429 bfd_fatal (archname);
1432 arch = bfd_fdopenr (archname, (const char *) NULL, f);
1433 if (arch == NULL)
1434 bfd_fatal (archname);
1435 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1437 bfd_nonfatal (archname);
1438 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1440 list_matching_formats (matching);
1441 free (matching);
1443 xexit (1);
1446 if (! bfd_has_map (arch))
1447 /* xgettext:c-format */
1448 fatal (_("%s: no archive map to update"), archname);
1450 bfd_update_armap_timestamp (arch);
1452 if (! bfd_close (arch))
1453 bfd_fatal (archname);
1454 #endif
1457 /* Things which are interesting to map over all or some of the files: */
1459 static void
1460 print_descr (abfd)
1461 bfd *abfd;
1463 print_arelt_descr (stdout, abfd, verbose);