Add -Wshadow to the gcc command line options used when compiling the binutils.
[binutils.git] / binutils / ar.c
blob15a7b477bf190463111fc14281b2124f91b77fa3
1 /* ar.c - Archive modify and extract.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 Bugs: should use getopt the way tar does (complete w/optional -) and
25 should have long options too. GNU ar used to check file against filesystem
26 in quick_update and replace operations (would check mtime). Doesn't warn
27 when name truncated. No way to specify pos_end. Error messages should be
28 more consistent. */
30 #include "sysdep.h"
31 #include "bfd.h"
32 #include "libiberty.h"
33 #include "progress.h"
34 #include "aout/ar.h"
35 #include "libbfd.h"
36 #include "bucomm.h"
37 #include "arsup.h"
38 #include "filenames.h"
39 #include "binemul.h"
40 #include "plugin.h"
41 #include <sys/stat.h>
43 #ifdef __GO32___
44 #define EXT_NAME_LEN 3 /* Bufflen of addition to name if it's MS-DOS. */
45 #else
46 #define EXT_NAME_LEN 6 /* Ditto for *NIX. */
47 #endif
49 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
51 struct ar_hdr *
52 bfd_special_undocumented_glue (bfd * abfd, const char *filename);
54 /* Static declarations. */
56 static void mri_emul (void);
57 static const char *normalize (const char *, bfd *);
58 static void remove_output (void);
59 static void map_over_members (bfd *, void (*)(bfd *), char **, int);
60 static void print_contents (bfd * member);
61 static void delete_members (bfd *, char **files_to_delete);
63 static void move_members (bfd *, char **files_to_move);
64 static void replace_members
65 (bfd *, char **files_to_replace, bfd_boolean quick);
66 static void print_descr (bfd * abfd);
67 static void write_archive (bfd *);
68 static int ranlib_only (const char *archname);
69 static int ranlib_touch (const char *archname);
70 static void usage (int);
72 /** Globals and flags. */
74 static int mri_mode;
76 /* This flag distinguishes between ar and ranlib:
77 1 means this is 'ranlib'; 0 means this is 'ar'.
78 -1 means if we should use argv[0] to decide. */
79 extern int is_ranlib;
81 /* Nonzero means don't warn about creating the archive file if necessary. */
82 int silent_create = 0;
84 /* Nonzero means describe each action performed. */
85 int verbose = 0;
87 /* Nonzero means preserve dates of members when extracting them. */
88 int preserve_dates = 0;
90 /* Nonzero means don't replace existing members whose dates are more recent
91 than the corresponding files. */
92 int newer_only = 0;
94 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
95 member). -1 means we've been explicitly asked to not write a symbol table;
96 +1 means we've been explicitly asked to write it;
97 0 is the default.
98 Traditionally, the default in BSD has been to not write the table.
99 However, for POSIX.2 compliance the default is now to write a symbol table
100 if any of the members are object files. */
101 int write_armap = 0;
103 /* Operate in deterministic mode: write zero for timestamps, uids,
104 and gids for archive members and the archive symbol table, and write
105 consistent file modes. */
106 int deterministic = 0;
108 /* Nonzero means it's the name of an existing member; position new or moved
109 files with respect to this one. */
110 char *posname = NULL;
112 /* Sez how to use `posname': pos_before means position before that member.
113 pos_after means position after that member. pos_end means always at end.
114 pos_default means default appropriately. For the latter two, `posname'
115 should also be zero. */
116 enum pos
118 pos_default, pos_before, pos_after, pos_end
119 } postype = pos_default;
121 static bfd **
122 get_pos_bfd (bfd **, enum pos, const char *);
124 /* For extract/delete only. If COUNTED_NAME_MODE is TRUE, we only
125 extract the COUNTED_NAME_COUNTER instance of that name. */
126 static bfd_boolean counted_name_mode = 0;
127 static int counted_name_counter = 0;
129 /* Whether to truncate names of files stored in the archive. */
130 static bfd_boolean ar_truncate = FALSE;
132 /* Whether to use a full file name match when searching an archive.
133 This is convenient for archives created by the Microsoft lib
134 program. */
135 static bfd_boolean full_pathname = FALSE;
137 /* Whether to create a "thin" archive (symbol index only -- no files). */
138 static bfd_boolean make_thin_archive = FALSE;
140 int interactive = 0;
142 static void
143 mri_emul (void)
145 interactive = isatty (fileno (stdin));
146 yyparse ();
149 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
150 COUNT is the length of the FILES chain; FUNCTION is called on each entry
151 whose name matches one in FILES. */
153 static void
154 map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
156 bfd *head;
157 int match_count;
159 if (count == 0)
161 for (head = arch->archive_next; head; head = head->archive_next)
163 PROGRESS (1);
164 function (head);
166 return;
169 /* This may appear to be a baroque way of accomplishing what we want.
170 However we have to iterate over the filenames in order to notice where
171 a filename is requested but does not exist in the archive. Ditto
172 mapping over each file each time -- we want to hack multiple
173 references. */
175 for (; count > 0; files++, count--)
177 bfd_boolean found = FALSE;
179 match_count = 0;
180 for (head = arch->archive_next; head; head = head->archive_next)
182 const char * filename;
184 PROGRESS (1);
185 filename = head->filename;
186 if (filename == NULL)
188 /* Some archive formats don't get the filenames filled in
189 until the elements are opened. */
190 struct stat buf;
191 bfd_stat_arch_elt (head, &buf);
193 else if (bfd_is_thin_archive (arch))
195 /* Thin archives store full pathnames. Need to normalize. */
196 filename = normalize (filename, arch);
199 if ((filename != NULL) &&
200 (!FILENAME_CMP (normalize (*files, arch), filename)))
202 ++match_count;
203 if (counted_name_mode
204 && match_count != counted_name_counter)
206 /* Counting, and didn't match on count; go on to the
207 next one. */
208 continue;
211 found = TRUE;
212 function (head);
216 if (!found)
217 /* xgettext:c-format */
218 fprintf (stderr, _("no entry %s in archive\n"), *files);
222 bfd_boolean operation_alters_arch = FALSE;
224 static void
225 usage (int help)
227 FILE *s;
229 s = help ? stdout : stderr;
231 if (! is_ranlib)
233 /* xgettext:c-format */
234 const char * command_line =
235 #if BFD_SUPPORTS_PLUGINS
236 _("Usage: %s [emulation options] [--plugin <name>] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n");
237 #else
238 _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n");
239 #endif
240 fprintf (s, command_line, program_name);
242 /* xgettext:c-format */
243 fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
244 fprintf (s, _(" commands:\n"));
245 fprintf (s, _(" d - delete file(s) from the archive\n"));
246 fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
247 fprintf (s, _(" p - print file(s) found in the archive\n"));
248 fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
249 fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
250 fprintf (s, _(" t - display contents of archive\n"));
251 fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
252 fprintf (s, _(" command specific modifiers:\n"));
253 fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
254 fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
255 fprintf (s, _(" [D] - use zero for timestamps and uids/gids\n"));
256 fprintf (s, _(" [N] - use instance [count] of name\n"));
257 fprintf (s, _(" [f] - truncate inserted file names\n"));
258 fprintf (s, _(" [P] - use full path names when matching\n"));
259 fprintf (s, _(" [o] - preserve original dates\n"));
260 fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
261 fprintf (s, _(" generic modifiers:\n"));
262 fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
263 fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
264 fprintf (s, _(" [S] - do not build a symbol table\n"));
265 fprintf (s, _(" [T] - make a thin archive\n"));
266 fprintf (s, _(" [v] - be verbose\n"));
267 fprintf (s, _(" [V] - display the version number\n"));
268 fprintf (s, _(" @<file> - read options from <file>\n"));
269 #if BFD_SUPPORTS_PLUGINS
270 fprintf (s, _(" optional:\n"));
271 fprintf (s, _(" --plugin <p> - load the specified plugin\n"));
272 #endif
273 ar_emul_usage (s);
275 else
277 /* xgettext:c-format */
278 fprintf (s, _("Usage: %s [options] archive\n"), program_name);
279 fprintf (s, _(" Generate an index to speed access to archives\n"));
280 fprintf (s, _(" The options are:\n\
281 @<file> Read options from <file>\n"));
282 #if BFD_SUPPORTS_PLUGINS
283 fprintf (s, _("\
284 --plugin <name> Load the specified plugin\n"));
285 #endif
286 fprintf (s, _("\
287 -t Update the archive's symbol map timestamp\n\
288 -h --help Print this help message\n\
289 -v --version Print version information\n"));
292 list_supported_targets (program_name, s);
294 if (REPORT_BUGS_TO[0] && 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 (const char *file, bfd *abfd)
306 const char *filename;
308 if (full_pathname)
309 return file;
311 filename = strrchr (file, '/');
312 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
314 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
315 char *bslash = strrchr (file, '\\');
317 if (filename == NULL || (bslash != NULL && bslash > filename))
318 filename = bslash;
319 if (filename == NULL && file[0] != '\0' && file[1] == ':')
320 filename = file + 1;
322 #endif
323 if (filename != (char *) NULL)
324 filename++;
325 else
326 filename = file;
328 if (ar_truncate
329 && abfd != NULL
330 && strlen (filename) > abfd->xvec->ar_max_namelen)
332 char *s;
334 /* Space leak. */
335 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
336 memcpy (s, filename, abfd->xvec->ar_max_namelen);
337 s[abfd->xvec->ar_max_namelen] = '\0';
338 filename = s;
341 return filename;
344 /* Remove any output file. This is only called via xatexit. */
346 static const char *output_filename = NULL;
347 static FILE *output_file = NULL;
348 static bfd *output_bfd = NULL;
350 static void
351 remove_output (void)
353 if (output_filename != NULL)
355 if (output_bfd != NULL)
356 bfd_cache_close (output_bfd);
357 if (output_file != NULL)
358 fclose (output_file);
359 unlink_if_ordinary (output_filename);
363 /* The option parsing should be in its own function.
364 It will be when I have getopt working. */
366 int main (int, char **);
369 main (int argc, char **argv)
371 char *arg_ptr;
372 char c;
373 enum
375 none = 0, del, replace, print_table,
376 print_files, extract, move, quick_append
377 } operation = none;
378 int arg_index;
379 char **files;
380 int file_count;
381 char *inarch_filename;
382 int show_version;
383 int i;
384 int do_posix = 0;
386 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
387 setlocale (LC_MESSAGES, "");
388 #endif
389 #if defined (HAVE_SETLOCALE)
390 setlocale (LC_CTYPE, "");
391 #endif
392 bindtextdomain (PACKAGE, LOCALEDIR);
393 textdomain (PACKAGE);
395 program_name = argv[0];
396 xmalloc_set_program_name (program_name);
397 #if BFD_SUPPORTS_PLUGINS
398 bfd_plugin_set_program_name (program_name);
399 #endif
401 expandargv (&argc, &argv);
403 if (is_ranlib < 0)
405 char *temp;
407 temp = strrchr (program_name, '/');
408 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
410 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
411 char *bslash = strrchr (program_name, '\\');
413 if (temp == NULL || (bslash != NULL && bslash > temp))
414 temp = bslash;
415 if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
416 temp = program_name + 1;
418 #endif
419 if (temp == NULL)
420 temp = program_name;
421 else
422 ++temp;
423 if (strlen (temp) >= 6
424 && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
425 is_ranlib = 1;
426 else
427 is_ranlib = 0;
430 if (argc > 1 && argv[1][0] == '-')
432 if (strcmp (argv[1], "--help") == 0)
433 usage (1);
434 else if (strcmp (argv[1], "--version") == 0)
436 if (is_ranlib)
437 print_version ("ranlib");
438 else
439 print_version ("ar");
443 START_PROGRESS (program_name, 0);
445 bfd_init ();
446 set_default_bfd_target ();
448 show_version = 0;
450 xatexit (remove_output);
452 for (i = 1; i < argc; i++)
453 if (! ar_emul_parse_arg (argv[i]))
454 break;
455 argv += (i - 1);
456 argc -= (i - 1);
458 if (is_ranlib)
460 int status = 0;
461 bfd_boolean touch = FALSE;
463 if (argc < 2
464 || strcmp (argv[1], "--help") == 0
465 || strcmp (argv[1], "-h") == 0
466 || strcmp (argv[1], "-H") == 0)
467 usage (0);
468 if (strcmp (argv[1], "-V") == 0
469 || strcmp (argv[1], "-v") == 0
470 || CONST_STRNEQ (argv[1], "--v"))
471 print_version ("ranlib");
472 arg_index = 1;
473 if (strcmp (argv[1], "-t") == 0)
475 ++arg_index;
476 touch = TRUE;
478 while (arg_index < argc)
480 if (! touch)
481 status |= ranlib_only (argv[arg_index]);
482 else
483 status |= ranlib_touch (argv[arg_index]);
484 ++arg_index;
486 xexit (status);
489 if (argc == 2 && strcmp (argv[1], "-M") == 0)
491 mri_emul ();
492 xexit (0);
495 if (argc < 2)
496 usage (0);
498 arg_index = 1;
499 arg_ptr = argv[arg_index];
501 if (strcmp (arg_ptr, "--plugin") == 0)
503 #if BFD_SUPPORTS_PLUGINS
504 if (argc < 4)
505 usage (1);
507 bfd_plugin_set_plugin (argv[2]);
509 arg_index += 2;
510 arg_ptr = argv[arg_index];
511 #else
512 fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
513 xexit (1);
514 #endif
517 if (*arg_ptr == '-')
519 /* When the first option starts with '-' we support POSIX-compatible
520 option parsing. */
521 do_posix = 1;
522 ++arg_ptr; /* compatibility */
527 while ((c = *arg_ptr++) != '\0')
529 switch (c)
531 case 'd':
532 case 'm':
533 case 'p':
534 case 'q':
535 case 'r':
536 case 't':
537 case 'x':
538 if (operation != none)
539 fatal (_("two different operation options specified"));
540 switch (c)
542 case 'd':
543 operation = del;
544 operation_alters_arch = TRUE;
545 break;
546 case 'm':
547 operation = move;
548 operation_alters_arch = TRUE;
549 break;
550 case 'p':
551 operation = print_files;
552 break;
553 case 'q':
554 operation = quick_append;
555 operation_alters_arch = TRUE;
556 break;
557 case 'r':
558 operation = replace;
559 operation_alters_arch = TRUE;
560 break;
561 case 't':
562 operation = print_table;
563 break;
564 case 'x':
565 operation = extract;
566 break;
568 case 'l':
569 break;
570 case 'c':
571 silent_create = 1;
572 break;
573 case 'o':
574 preserve_dates = 1;
575 break;
576 case 'V':
577 show_version = TRUE;
578 break;
579 case 's':
580 write_armap = 1;
581 break;
582 case 'S':
583 write_armap = -1;
584 break;
585 case 'u':
586 newer_only = 1;
587 break;
588 case 'v':
589 verbose = 1;
590 break;
591 case 'a':
592 postype = pos_after;
593 break;
594 case 'b':
595 postype = pos_before;
596 break;
597 case 'i':
598 postype = pos_before;
599 break;
600 case 'M':
601 mri_mode = 1;
602 break;
603 case 'N':
604 counted_name_mode = TRUE;
605 break;
606 case 'f':
607 ar_truncate = TRUE;
608 break;
609 case 'P':
610 full_pathname = TRUE;
611 break;
612 case 'T':
613 make_thin_archive = TRUE;
614 break;
615 case 'D':
616 deterministic = TRUE;
617 break;
618 default:
619 /* xgettext:c-format */
620 non_fatal (_("illegal option -- %c"), c);
621 usage (0);
625 /* With POSIX-compatible option parsing continue with the next
626 argument if it starts with '-'. */
627 if (do_posix && arg_index + 1 < argc && argv[arg_index + 1][0] == '-')
628 arg_ptr = argv[++arg_index] + 1;
629 else
630 do_posix = 0;
632 while (do_posix);
634 if (show_version)
635 print_version ("ar");
637 ++arg_index;
638 if (arg_index >= argc)
639 usage (0);
641 if (mri_mode)
643 mri_emul ();
645 else
647 bfd *arch;
649 /* We don't use do_quick_append any more. Too many systems
650 expect ar to always rebuild the symbol table even when q is
651 used. */
653 /* We can't write an armap when using ar q, so just do ar r
654 instead. */
655 if (operation == quick_append && write_armap)
656 operation = replace;
658 if ((operation == none || operation == print_table)
659 && write_armap == 1)
660 xexit (ranlib_only (argv[arg_index]));
662 if (operation == none)
663 fatal (_("no operation specified"));
665 if (newer_only && operation != replace)
666 fatal (_("`u' is only meaningful with the `r' option."));
668 if (newer_only && deterministic)
669 fatal (_("`u' is not meaningful with the `D' option."));
671 if (postype != pos_default)
672 posname = argv[arg_index++];
674 if (counted_name_mode)
676 if (operation != extract && operation != del)
677 fatal (_("`N' is only meaningful with the `x' and `d' options."));
678 counted_name_counter = atoi (argv[arg_index++]);
679 if (counted_name_counter <= 0)
680 fatal (_("Value for `N' must be positive."));
683 inarch_filename = argv[arg_index++];
685 files = arg_index < argc ? argv + arg_index : NULL;
686 file_count = argc - arg_index;
688 arch = open_inarch (inarch_filename,
689 files == NULL ? (char *) NULL : files[0]);
691 if (operation == extract && bfd_is_thin_archive (arch))
692 fatal (_("`x' cannot be used on thin archives."));
694 switch (operation)
696 case print_table:
697 map_over_members (arch, print_descr, files, file_count);
698 break;
700 case print_files:
701 map_over_members (arch, print_contents, files, file_count);
702 break;
704 case extract:
705 map_over_members (arch, extract_file, files, file_count);
706 break;
708 case del:
709 if (files != NULL)
710 delete_members (arch, files);
711 else
712 output_filename = NULL;
713 break;
715 case move:
716 if (files != NULL)
717 move_members (arch, files);
718 else
719 output_filename = NULL;
720 break;
722 case replace:
723 case quick_append:
724 if (files != NULL || write_armap > 0)
725 replace_members (arch, files, operation == quick_append);
726 else
727 output_filename = NULL;
728 break;
730 /* Shouldn't happen! */
731 default:
732 /* xgettext:c-format */
733 fatal (_("internal error -- this option not implemented"));
737 END_PROGRESS (program_name);
739 xexit (0);
740 return 0;
743 bfd *
744 open_inarch (const char *archive_filename, const char *file)
746 const char *target;
747 bfd **last_one;
748 bfd *next_one;
749 struct stat sbuf;
750 bfd *arch;
751 char **matching;
753 bfd_set_error (bfd_error_no_error);
755 target = NULL;
757 if (stat (archive_filename, &sbuf) != 0)
759 #if !defined(__GO32__) || defined(__DJGPP__)
761 /* FIXME: I don't understand why this fragment was ifndef'ed
762 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
763 stat() works just fine in v2.x, so I think this should be
764 removed. For now, I enable it for DJGPP v2. -- EZ. */
766 /* KLUDGE ALERT! Temporary fix until I figger why
767 stat() is wrong ... think it's buried in GO32's IDT - Jax */
768 if (errno != ENOENT)
769 bfd_fatal (archive_filename);
770 #endif
772 if (!operation_alters_arch)
774 fprintf (stderr, "%s: ", program_name);
775 perror (archive_filename);
776 maybequit ();
777 return NULL;
780 /* Try to figure out the target to use for the archive from the
781 first object on the list. */
782 if (file != NULL)
784 bfd *obj;
786 obj = bfd_openr (file, NULL);
787 if (obj != NULL)
789 if (bfd_check_format (obj, bfd_object))
790 target = bfd_get_target (obj);
791 (void) bfd_close (obj);
795 /* Create an empty archive. */
796 arch = bfd_openw (archive_filename, target);
797 if (arch == NULL
798 || ! bfd_set_format (arch, bfd_archive)
799 || ! bfd_close (arch))
800 bfd_fatal (archive_filename);
801 else if (!silent_create)
802 non_fatal (_("creating %s"), archive_filename);
804 /* If we die creating a new archive, don't leave it around. */
805 output_filename = archive_filename;
808 arch = bfd_openr (archive_filename, target);
809 if (arch == NULL)
811 bloser:
812 bfd_fatal (archive_filename);
815 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
817 bfd_nonfatal (archive_filename);
818 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
820 list_matching_formats (matching);
821 free (matching);
823 xexit (1);
826 last_one = &(arch->archive_next);
827 /* Read all the contents right away, regardless. */
828 for (next_one = bfd_openr_next_archived_file (arch, NULL);
829 next_one;
830 next_one = bfd_openr_next_archived_file (arch, next_one))
832 PROGRESS (1);
833 *last_one = next_one;
834 last_one = &next_one->archive_next;
836 *last_one = (bfd *) NULL;
837 if (bfd_get_error () != bfd_error_no_more_archived_files)
838 goto bloser;
839 return arch;
842 static void
843 print_contents (bfd *abfd)
845 size_t ncopied = 0;
846 char *cbuf = (char *) xmalloc (BUFSIZE);
847 struct stat buf;
848 size_t size;
849 if (bfd_stat_arch_elt (abfd, &buf) != 0)
850 /* xgettext:c-format */
851 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
853 if (verbose)
854 /* xgettext:c-format */
855 printf (_("\n<%s>\n\n"), bfd_get_filename (abfd));
857 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
859 size = buf.st_size;
860 while (ncopied < size)
863 size_t nread;
864 size_t tocopy = size - ncopied;
865 if (tocopy > BUFSIZE)
866 tocopy = BUFSIZE;
868 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
869 if (nread != tocopy)
870 /* xgettext:c-format */
871 fatal (_("%s is not a valid archive"),
872 bfd_get_filename (bfd_my_archive (abfd)));
874 /* fwrite in mingw32 may return int instead of size_t. Cast the
875 return value to size_t to avoid comparison between signed and
876 unsigned values. */
877 if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread)
878 fatal ("stdout: %s", strerror (errno));
879 ncopied += tocopy;
881 free (cbuf);
884 /* Extract a member of the archive into its own file.
886 We defer opening the new file until after we have read a BUFSIZ chunk of the
887 old one, since we know we have just read the archive header for the old
888 one. Since most members are shorter than BUFSIZ, this means we will read
889 the old header, read the old data, write a new inode for the new file, and
890 write the new data, and be done. This 'optimization' is what comes from
891 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
892 Gilmore */
894 void
895 extract_file (bfd *abfd)
897 FILE *ostream;
898 char *cbuf = (char *) xmalloc (BUFSIZE);
899 size_t nread, tocopy;
900 size_t ncopied = 0;
901 size_t size;
902 struct stat buf;
904 if (bfd_stat_arch_elt (abfd, &buf) != 0)
905 /* xgettext:c-format */
906 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
907 size = buf.st_size;
909 if (verbose)
910 printf ("x - %s\n", bfd_get_filename (abfd));
912 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
914 ostream = NULL;
915 if (size == 0)
917 /* Seems like an abstraction violation, eh? Well it's OK! */
918 output_filename = bfd_get_filename (abfd);
920 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
921 if (ostream == NULL)
923 perror (bfd_get_filename (abfd));
924 xexit (1);
927 output_file = ostream;
929 else
930 while (ncopied < size)
932 tocopy = size - ncopied;
933 if (tocopy > BUFSIZE)
934 tocopy = BUFSIZE;
936 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
937 if (nread != tocopy)
938 /* xgettext:c-format */
939 fatal (_("%s is not a valid archive"),
940 bfd_get_filename (bfd_my_archive (abfd)));
942 /* See comment above; this saves disk arm motion */
943 if (ostream == NULL)
945 /* Seems like an abstraction violation, eh? Well it's OK! */
946 output_filename = bfd_get_filename (abfd);
948 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
949 if (ostream == NULL)
951 perror (bfd_get_filename (abfd));
952 xexit (1);
955 output_file = ostream;
958 /* fwrite in mingw32 may return int instead of size_t. Cast
959 the return value to size_t to avoid comparison between
960 signed and unsigned values. */
961 if ((size_t) fwrite (cbuf, 1, nread, ostream) != nread)
962 fatal ("%s: %s", output_filename, strerror (errno));
963 ncopied += tocopy;
966 if (ostream != NULL)
967 fclose (ostream);
969 output_file = NULL;
970 output_filename = NULL;
972 chmod (bfd_get_filename (abfd), buf.st_mode);
974 if (preserve_dates)
976 /* Set access time to modification time. Only st_mtime is
977 initialized by bfd_stat_arch_elt. */
978 buf.st_atime = buf.st_mtime;
979 set_times (bfd_get_filename (abfd), &buf);
982 free (cbuf);
985 static void
986 write_archive (bfd *iarch)
988 bfd *obfd;
989 char *old_name, *new_name;
990 bfd *contents_head = iarch->archive_next;
992 old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
993 strcpy (old_name, bfd_get_filename (iarch));
994 new_name = make_tempname (old_name);
996 if (new_name == NULL)
997 bfd_fatal ("could not create temporary file whilst writing archive");
999 output_filename = new_name;
1001 obfd = bfd_openw (new_name, bfd_get_target (iarch));
1003 if (obfd == NULL)
1004 bfd_fatal (old_name);
1006 output_bfd = obfd;
1008 bfd_set_format (obfd, bfd_archive);
1010 /* Request writing the archive symbol table unless we've
1011 been explicitly requested not to. */
1012 obfd->has_armap = write_armap >= 0;
1014 if (ar_truncate)
1016 /* This should really use bfd_set_file_flags, but that rejects
1017 archives. */
1018 obfd->flags |= BFD_TRADITIONAL_FORMAT;
1021 if (deterministic)
1022 obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1024 if (make_thin_archive || bfd_is_thin_archive (iarch))
1025 bfd_is_thin_archive (obfd) = 1;
1027 if (!bfd_set_archive_head (obfd, contents_head))
1028 bfd_fatal (old_name);
1030 if (!bfd_close (obfd))
1031 bfd_fatal (old_name);
1033 output_bfd = NULL;
1034 output_filename = NULL;
1036 /* We don't care if this fails; we might be creating the archive. */
1037 bfd_close (iarch);
1039 if (smart_rename (new_name, old_name, 0) != 0)
1040 xexit (1);
1043 /* Return a pointer to the pointer to the entry which should be rplacd'd
1044 into when altering. DEFAULT_POS should be how to interpret pos_default,
1045 and should be a pos value. */
1047 static bfd **
1048 get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1050 bfd **after_bfd = contents;
1051 enum pos realpos;
1052 const char *realposname;
1054 if (postype == pos_default)
1056 realpos = default_pos;
1057 realposname = default_posname;
1059 else
1061 realpos = postype;
1062 realposname = posname;
1065 if (realpos == pos_end)
1067 while (*after_bfd)
1068 after_bfd = &((*after_bfd)->archive_next);
1070 else
1072 for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
1073 if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1075 if (realpos == pos_after)
1076 after_bfd = &(*after_bfd)->archive_next;
1077 break;
1080 return after_bfd;
1083 static void
1084 delete_members (bfd *arch, char **files_to_delete)
1086 bfd **current_ptr_ptr;
1087 bfd_boolean found;
1088 bfd_boolean something_changed = FALSE;
1089 int match_count;
1091 for (; *files_to_delete != NULL; ++files_to_delete)
1093 /* In a.out systems, the armap is optional. It's also called
1094 __.SYMDEF. So if the user asked to delete it, we should remember
1095 that fact. This isn't quite right for COFF systems (where
1096 __.SYMDEF might be regular member), but it's very unlikely
1097 to be a problem. FIXME */
1099 if (!strcmp (*files_to_delete, "__.SYMDEF"))
1101 arch->has_armap = FALSE;
1102 write_armap = -1;
1103 continue;
1106 found = FALSE;
1107 match_count = 0;
1108 current_ptr_ptr = &(arch->archive_next);
1109 while (*current_ptr_ptr)
1111 if (FILENAME_CMP (normalize (*files_to_delete, arch),
1112 (*current_ptr_ptr)->filename) == 0)
1114 ++match_count;
1115 if (counted_name_mode
1116 && match_count != counted_name_counter)
1118 /* Counting, and didn't match on count; go on to the
1119 next one. */
1121 else
1123 found = TRUE;
1124 something_changed = TRUE;
1125 if (verbose)
1126 printf ("d - %s\n",
1127 *files_to_delete);
1128 *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
1129 goto next_file;
1133 current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1136 if (verbose && !found)
1138 /* xgettext:c-format */
1139 printf (_("No member named `%s'\n"), *files_to_delete);
1141 next_file:
1145 if (something_changed)
1146 write_archive (arch);
1147 else
1148 output_filename = NULL;
1152 /* Reposition existing members within an archive */
1154 static void
1155 move_members (bfd *arch, char **files_to_move)
1157 bfd **after_bfd; /* New entries go after this one */
1158 bfd **current_ptr_ptr; /* cdr pointer into contents */
1160 for (; *files_to_move; ++files_to_move)
1162 current_ptr_ptr = &(arch->archive_next);
1163 while (*current_ptr_ptr)
1165 bfd *current_ptr = *current_ptr_ptr;
1166 if (FILENAME_CMP (normalize (*files_to_move, arch),
1167 current_ptr->filename) == 0)
1169 /* Move this file to the end of the list - first cut from
1170 where it is. */
1171 bfd *link_bfd;
1172 *current_ptr_ptr = current_ptr->archive_next;
1174 /* Now glue to end */
1175 after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1176 link_bfd = *after_bfd;
1177 *after_bfd = current_ptr;
1178 current_ptr->archive_next = link_bfd;
1180 if (verbose)
1181 printf ("m - %s\n", *files_to_move);
1183 goto next_file;
1186 current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1188 /* xgettext:c-format */
1189 fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1191 next_file:;
1194 write_archive (arch);
1197 /* Ought to default to replacing in place, but this is existing practice! */
1199 static void
1200 replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
1202 bfd_boolean changed = FALSE;
1203 bfd **after_bfd; /* New entries go after this one. */
1204 bfd *current;
1205 bfd **current_ptr;
1207 while (files_to_move && *files_to_move)
1209 if (! quick)
1211 current_ptr = &arch->archive_next;
1212 while (*current_ptr)
1214 current = *current_ptr;
1216 /* For compatibility with existing ar programs, we
1217 permit the same file to be added multiple times. */
1218 if (FILENAME_CMP (normalize (*files_to_move, arch),
1219 normalize (current->filename, arch)) == 0
1220 && current->arelt_data != NULL)
1222 if (newer_only)
1224 struct stat fsbuf, asbuf;
1226 if (stat (*files_to_move, &fsbuf) != 0)
1228 if (errno != ENOENT)
1229 bfd_fatal (*files_to_move);
1230 goto next_file;
1232 if (bfd_stat_arch_elt (current, &asbuf) != 0)
1233 /* xgettext:c-format */
1234 fatal (_("internal stat error on %s"),
1235 current->filename);
1237 if (fsbuf.st_mtime <= asbuf.st_mtime)
1238 goto next_file;
1241 after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
1242 current->filename);
1243 if (ar_emul_replace (after_bfd, *files_to_move,
1244 verbose))
1246 /* Snip out this entry from the chain. */
1247 *current_ptr = (*current_ptr)->archive_next;
1248 changed = TRUE;
1251 goto next_file;
1253 current_ptr = &(current->archive_next);
1257 /* Add to the end of the archive. */
1258 after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1260 if (ar_emul_append (after_bfd, *files_to_move, verbose,
1261 make_thin_archive))
1262 changed = TRUE;
1264 next_file:;
1266 files_to_move++;
1269 if (changed)
1270 write_archive (arch);
1271 else
1272 output_filename = NULL;
1275 static int
1276 ranlib_only (const char *archname)
1278 bfd *arch;
1280 if (get_file_size (archname) < 1)
1281 return 1;
1282 write_armap = 1;
1283 arch = open_inarch (archname, (char *) NULL);
1284 if (arch == NULL)
1285 xexit (1);
1286 write_archive (arch);
1287 return 0;
1290 /* Update the timestamp of the symbol map of an archive. */
1292 static int
1293 ranlib_touch (const char *archname)
1295 #ifdef __GO32__
1296 /* I don't think updating works on go32. */
1297 ranlib_only (archname);
1298 #else
1299 int f;
1300 bfd *arch;
1301 char **matching;
1303 if (get_file_size (archname) < 1)
1304 return 1;
1305 f = open (archname, O_RDWR | O_BINARY, 0);
1306 if (f < 0)
1308 bfd_set_error (bfd_error_system_call);
1309 bfd_fatal (archname);
1312 arch = bfd_fdopenr (archname, (const char *) NULL, f);
1313 if (arch == NULL)
1314 bfd_fatal (archname);
1315 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1317 bfd_nonfatal (archname);
1318 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1320 list_matching_formats (matching);
1321 free (matching);
1323 xexit (1);
1326 if (! bfd_has_map (arch))
1327 /* xgettext:c-format */
1328 fatal (_("%s: no archive map to update"), archname);
1330 bfd_update_armap_timestamp (arch);
1332 if (! bfd_close (arch))
1333 bfd_fatal (archname);
1334 #endif
1335 return 0;
1338 /* Things which are interesting to map over all or some of the files: */
1340 static void
1341 print_descr (bfd *abfd)
1343 print_arelt_descr (stdout, abfd, verbose);