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