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