xref: /netbsd-src/external/gpl3/binutils.old/dist/binutils/ar.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 /* ar.c - Archive modify and extract.
2    Copyright (C) 1991-2022 Free Software Foundation, Inc.
3 
4    This file is part of GNU Binutils.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 /*
22    Bugs: GNU ar used to check file against filesystem in quick_update and
23    replace operations (would check mtime). Doesn't warn when name truncated.
24    No way to specify pos_end. Error messages should be more consistent.  */
25 
26 #include "sysdep.h"
27 #include "bfd.h"
28 #include "libiberty.h"
29 #include "progress.h"
30 #include "getopt.h"
31 #include "aout/ar.h"
32 #include "bucomm.h"
33 #include "arsup.h"
34 #include "filenames.h"
35 #include "binemul.h"
36 #include "plugin-api.h"
37 #include "plugin.h"
38 #include "ansidecl.h"
39 
40 #ifdef __GO32___
41 #define EXT_NAME_LEN 3		/* Bufflen of addition to name if it's MS-DOS.  */
42 #else
43 #define EXT_NAME_LEN 6		/* Ditto for *NIX.  */
44 #endif
45 
46 /* Static declarations.  */
47 
48 static void mri_emul (void);
49 static const char *normalize (const char *, bfd *);
50 static void remove_output (void);
51 static void map_over_members (bfd *, void (*)(bfd *), char **, int);
52 static void print_contents (bfd * member);
53 static void delete_members (bfd *, char **files_to_delete);
54 
55 static void move_members (bfd *, char **files_to_move);
56 static void replace_members
57   (bfd *, char **files_to_replace, bool quick);
58 static void print_descr (bfd * abfd);
59 static void write_archive (bfd *);
60 static int  ranlib_only (const char *archname);
61 static int  ranlib_touch (const char *archname);
62 static void usage (int);
63 
64 /** Globals and flags.  */
65 
66 static int mri_mode;
67 
68 /* This flag distinguishes between ar and ranlib:
69    1 means this is 'ranlib'; 0 means this is 'ar'.
70    -1 means if we should use argv[0] to decide.  */
71 extern int is_ranlib;
72 
73 /* Nonzero means don't warn about creating the archive file if necessary.  */
74 int silent_create = 0;
75 
76 /* Nonzero means describe each action performed.  */
77 int verbose = 0;
78 
79 /* Nonzero means display offsets of files in the archive.  */
80 int display_offsets = 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 = -1;			/* Determinism indeterminate.  */
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 enum operations
117   {
118     none = 0, del, replace, print_table,
119     print_files, extract, move, quick_append
120   } operation = none;
121 
122 static bfd **
123 get_pos_bfd (bfd **, enum pos, const char *);
124 
125 /* For extract/delete only.  If COUNTED_NAME_MODE is TRUE, we only
126    extract the COUNTED_NAME_COUNTER instance of that name.  */
127 static bool counted_name_mode = 0;
128 static int counted_name_counter = 0;
129 
130 /* Whether to truncate names of files stored in the archive.  */
131 static bool ar_truncate = false;
132 
133 /* Whether to use a full file name match when searching an archive.
134    This is convenient for archives created by the Microsoft lib
135    program.  */
136 static bool full_pathname = false;
137 
138 /* Whether to create a "thin" archive (symbol index only -- no files).  */
139 static bool make_thin_archive = false;
140 
141 #define LIBDEPS	"__.LIBDEP"
142 /* Text to store in the __.LIBDEP archive element for the linker to use.  */
143 static char * libdeps = NULL;
144 static bfd *  libdeps_bfd = NULL;
145 
146 static int show_version = 0;
147 
148 static int show_help = 0;
149 
150 #if BFD_SUPPORTS_PLUGINS
151 static const char *plugin_target = "plugin";
152 #else
153 static const char *plugin_target = NULL;
154 #endif
155 
156 static const char *target = NULL;
157 
158 enum long_option_numbers
159 {
160   OPTION_PLUGIN = 201,
161   OPTION_TARGET,
162   OPTION_OUTPUT
163 };
164 
165 static const char * output_dir = NULL;
166 
167 static struct option long_options[] =
168 {
169   {"help", no_argument, &show_help, 1},
170   {"plugin", required_argument, NULL, OPTION_PLUGIN},
171   {"target", required_argument, NULL, OPTION_TARGET},
172   {"version", no_argument, &show_version, 1},
173   {"output", required_argument, NULL, OPTION_OUTPUT},
174   {"record-libdeps", required_argument, NULL, 'l'},
175   {"thin", no_argument, NULL, 'T'},
176   {NULL, no_argument, NULL, 0}
177 };
178 
179 int interactive = 0;
180 
181 static void
182 mri_emul (void)
183 {
184   interactive = isatty (fileno (stdin));
185   yyparse ();
186 }
187 
188 /* If COUNT is 0, then FUNCTION is called once on each entry.  If nonzero,
189    COUNT is the length of the FILES chain; FUNCTION is called on each entry
190    whose name matches one in FILES.  */
191 
192 static void
193 map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
194 {
195   bfd *head;
196   int match_count;
197 
198   if (count == 0)
199     {
200       for (head = arch->archive_next; head; head = head->archive_next)
201 	{
202 	  PROGRESS (1);
203 	  function (head);
204 	}
205       return;
206     }
207 
208   /* This may appear to be a baroque way of accomplishing what we want.
209      However we have to iterate over the filenames in order to notice where
210      a filename is requested but does not exist in the archive.  Ditto
211      mapping over each file each time -- we want to hack multiple
212      references.  */
213 
214   for (head = arch->archive_next; head; head = head->archive_next)
215     head->archive_pass = 0;
216 
217   for (; count > 0; files++, count--)
218     {
219       bool found = false;
220 
221       match_count = 0;
222       for (head = arch->archive_next; head; head = head->archive_next)
223 	{
224 	  const char * filename;
225 
226 	  PROGRESS (1);
227 	  /* PR binutils/15796: Once an archive element has been matched
228 	     do not match it again.  If the user provides multiple same-named
229 	     parameters on the command line their intent is to match multiple
230 	     same-named entries in the archive, not the same entry multiple
231 	     times.  */
232 	  if (head->archive_pass)
233 	    continue;
234 
235 	  filename = bfd_get_filename (head);
236 	  if (filename == NULL)
237 	    {
238 	      /* Some archive formats don't get the filenames filled in
239 		 until the elements are opened.  */
240 	      struct stat buf;
241 	      bfd_stat_arch_elt (head, &buf);
242 	    }
243 	  else if (bfd_is_thin_archive (arch))
244 	    {
245 	      /* Thin archives store full pathnames.  Need to normalize.  */
246 	      filename = normalize (filename, arch);
247 	    }
248 
249 	  if (filename != NULL
250 	      && !FILENAME_CMP (normalize (*files, arch), filename))
251 	    {
252 	      ++match_count;
253 	      if (counted_name_mode
254 		  && match_count != counted_name_counter)
255 		{
256 		  /* Counting, and didn't match on count; go on to the
257                      next one.  */
258 		  continue;
259 		}
260 
261 	      found = true;
262 	      function (head);
263 	      head->archive_pass = 1;
264 	      /* PR binutils/15796: Once a file has been matched, do not
265 		 match any more same-named files in the archive.  If the
266 		 user does want to match multiple same-name files in an
267 		 archive they should provide multiple same-name parameters
268 		 to the ar command.  */
269 	      break;
270 	    }
271 	}
272 
273       if (!found)
274 	/* xgettext:c-format */
275 	fprintf (stderr, _("no entry %s in archive\n"), *files);
276     }
277 }
278 
279 bool operation_alters_arch = false;
280 
281 static void
282 usage (int help)
283 {
284   FILE *s;
285 
286 #if BFD_SUPPORTS_PLUGINS
287   /* xgettext:c-format */
288   const char *command_line
289     = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
290 	" [--plugin <name>] [member-name] [count] archive-file file...\n");
291 
292 #else
293   /* xgettext:c-format */
294   const char *command_line
295     = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
296 	" [member-name] [count] archive-file file...\n");
297 #endif
298   s = help ? stdout : stderr;
299 
300   fprintf (s, command_line, program_name);
301 
302   /* xgettext:c-format */
303   fprintf (s, _("       %s -M [<mri-script]\n"), program_name);
304   fprintf (s, _(" commands:\n"));
305   fprintf (s, _("  d            - delete file(s) from the archive\n"));
306   fprintf (s, _("  m[ab]        - move file(s) in the archive\n"));
307   fprintf (s, _("  p            - print file(s) found in the archive\n"));
308   fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
309   fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
310   fprintf (s, _("  s            - act as ranlib\n"));
311   fprintf (s, _("  t[O][v]      - display contents of the archive\n"));
312   fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
313   fprintf (s, _(" command specific modifiers:\n"));
314   fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
315   fprintf (s, _("  [b]          - put file(s) before [member-name] (same as [i])\n"));
316   if (DEFAULT_AR_DETERMINISTIC)
317     {
318       fprintf (s, _("\
319   [D]          - use zero for timestamps and uids/gids (default)\n"));
320       fprintf (s, _("\
321   [U]          - use actual timestamps and uids/gids\n"));
322     }
323   else
324     {
325       fprintf (s, _("\
326   [D]          - use zero for timestamps and uids/gids\n"));
327       fprintf (s, _("\
328   [U]          - use actual timestamps and uids/gids (default)\n"));
329     }
330   fprintf (s, _("  [N]          - use instance [count] of name\n"));
331   fprintf (s, _("  [f]          - truncate inserted file names\n"));
332   fprintf (s, _("  [P]          - use full path names when matching\n"));
333   fprintf (s, _("  [o]          - preserve original dates\n"));
334   fprintf (s, _("  [O]          - display offsets of files in the archive\n"));
335   fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
336   fprintf (s, _(" generic modifiers:\n"));
337   fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
338   fprintf (s, _("  [s]          - create an archive index (cf. ranlib)\n"));
339   fprintf (s, _("  [l <text> ]  - specify the dependencies of this library\n"));
340   fprintf (s, _("  [S]          - do not build a symbol table\n"));
341   fprintf (s, _("  [T]          - deprecated, use --thin instead\n"));
342   fprintf (s, _("  [v]          - be verbose\n"));
343   fprintf (s, _("  [V]          - display the version number\n"));
344   fprintf (s, _("  @<file>      - read options from <file>\n"));
345   fprintf (s, _("  --target=BFDNAME - specify the target object format as BFDNAME\n"));
346   fprintf (s, _("  --output=DIRNAME - specify the output directory for extraction operations\n"));
347   fprintf (s, _("  --record-libdeps=<text> - specify the dependencies of this library\n"));
348   fprintf (s, _("  --thin       - make a thin archive\n"));
349 #if BFD_SUPPORTS_PLUGINS
350   fprintf (s, _(" optional:\n"));
351   fprintf (s, _("  --plugin <p> - load the specified plugin\n"));
352 #endif
353 
354   ar_emul_usage (s);
355 
356   list_supported_targets (program_name, s);
357 
358   if (REPORT_BUGS_TO[0] && help)
359     fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
360 
361   xexit (help ? 0 : 1);
362 }
363 
364 static void
365 ranlib_usage (int help)
366 {
367   FILE *s;
368 
369   s = help ? stdout : stderr;
370 
371   /* xgettext:c-format */
372   fprintf (s, _("Usage: %s [options] archive\n"), program_name);
373   fprintf (s, _(" Generate an index to speed access to archives\n"));
374   fprintf (s, _(" The options are:\n\
375   @<file>                      Read options from <file>\n"));
376 #if BFD_SUPPORTS_PLUGINS
377   fprintf (s, _("\
378   --plugin <name>              Load the specified plugin\n"));
379 #endif
380   if (DEFAULT_AR_DETERMINISTIC)
381     fprintf (s, _("\
382   -D                           Use zero for symbol map timestamp (default)\n\
383   -U                           Use an actual symbol map timestamp\n"));
384   else
385     fprintf (s, _("\
386   -D                           Use zero for symbol map timestamp\n\
387   -U                           Use actual symbol map timestamp (default)\n"));
388   fprintf (s, _("\
389   -t                           Update the archive's symbol map timestamp\n\
390   -h --help                    Print this help message\n\
391   -v --version                 Print version information\n"));
392 
393   list_supported_targets (program_name, s);
394 
395   if (REPORT_BUGS_TO[0] && help)
396     fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
397 
398   xexit (help ? 0 : 1);
399 }
400 
401 /* Normalize a file name specified on the command line into a file
402    name which we will use in an archive.  */
403 
404 static const char *
405 normalize (const char *file, bfd *abfd)
406 {
407   const char *filename;
408 
409   if (full_pathname)
410     return file;
411 
412   filename = lbasename (file);
413 
414   if (ar_truncate
415       && abfd != NULL
416       && strlen (filename) > abfd->xvec->ar_max_namelen)
417     {
418       char *s;
419 
420       /* Space leak.  */
421       s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
422       memcpy (s, filename, abfd->xvec->ar_max_namelen);
423       s[abfd->xvec->ar_max_namelen] = '\0';
424       filename = s;
425     }
426 
427   return filename;
428 }
429 
430 /* Remove any output file.  This is only called via xatexit.  */
431 
432 static const char *output_filename = NULL;
433 static FILE *output_file = NULL;
434 static bfd *output_bfd = NULL;
435 
436 static void
437 remove_output (void)
438 {
439   if (output_filename != NULL)
440     {
441       if (output_bfd != NULL)
442 	bfd_cache_close (output_bfd);
443       if (output_file != NULL)
444 	fclose (output_file);
445       unlink_if_ordinary (output_filename);
446     }
447 }
448 
449 static char **
450 decode_options (int argc, char **argv)
451 {
452   int c;
453 
454   /* Convert old-style ar call by exploding option element and rearranging
455      options accordingly.  */
456 
457  restart:
458   if (argc > 1 && argv[1][0] != '-')
459     {
460       int new_argc;		/* argc value for rearranged arguments */
461       char **new_argv;		/* argv value for rearranged arguments */
462       char *const *in;		/* cursor into original argv */
463       char **out;		/* cursor into rearranged argv */
464       const char *letter;	/* cursor into old option letters */
465       char buffer[3];		/* constructed option buffer */
466 
467       /* Initialize a constructed option.  */
468 
469       buffer[0] = '-';
470       buffer[2] = '\0';
471 
472       /* Allocate a new argument array, and copy program name in it.  */
473 
474       new_argc = argc - 1 + strlen (argv[1]);
475       new_argv = xmalloc ((new_argc + 1) * sizeof (*argv));
476       in = argv;
477       out = new_argv;
478       *out++ = *in++;
479 
480       /* Copy each old letter option as a separate option.  */
481 
482       for (letter = *in++; *letter; letter++)
483 	{
484 	  buffer[1] = *letter;
485 	  *out++ = xstrdup (buffer);
486 	}
487 
488       /* Copy all remaining options.  */
489 
490       while (in < argv + argc)
491 	*out++ = *in++;
492       *out = NULL;
493 
494       /* Replace the old option list by the new one.  */
495 
496       argc = new_argc;
497       argv = new_argv;
498     }
499 
500   while ((c = getopt_long (argc, argv, "hdmpqrtxl:coOVsSuvabiMNfPTDU",
501 			   long_options, NULL)) != EOF)
502     {
503       switch (c)
504         {
505         case 'd':
506         case 'm':
507         case 'p':
508         case 'q':
509         case 'r':
510         case 't':
511         case 'x':
512           if (operation != none)
513             fatal (_("two different operation options specified"));
514 	  break;
515 	}
516 
517       switch (c)
518         {
519         case 'h':
520 	  show_help = 1;
521 	  break;
522         case 'd':
523           operation = del;
524           operation_alters_arch = true;
525           break;
526         case 'm':
527           operation = move;
528           operation_alters_arch = true;
529           break;
530         case 'p':
531           operation = print_files;
532           break;
533         case 'q':
534           operation = quick_append;
535           operation_alters_arch = true;
536           break;
537         case 'r':
538           operation = replace;
539           operation_alters_arch = true;
540           break;
541         case 't':
542           operation = print_table;
543           break;
544         case 'x':
545           operation = extract;
546           break;
547         case 'l':
548           if (libdeps != NULL)
549             fatal (_("libdeps specified more than once"));
550           libdeps = optarg;
551           break;
552         case 'c':
553           silent_create = 1;
554           break;
555         case 'o':
556           preserve_dates = 1;
557           break;
558         case 'O':
559           display_offsets = 1;
560           break;
561         case 'V':
562           show_version = true;
563           break;
564         case 's':
565           write_armap = 1;
566           break;
567         case 'S':
568           write_armap = -1;
569           break;
570         case 'u':
571           newer_only = 1;
572           break;
573         case 'v':
574           verbose = 1;
575           break;
576         case 'a':
577           postype = pos_after;
578           break;
579         case 'b':
580           postype = pos_before;
581           break;
582         case 'i':
583           postype = pos_before;
584           break;
585         case 'M':
586           mri_mode = 1;
587           break;
588         case 'N':
589           counted_name_mode = true;
590           break;
591         case 'f':
592           ar_truncate = true;
593           break;
594         case 'P':
595           full_pathname = true;
596           break;
597         case 'T':
598           make_thin_archive = true;
599           break;
600         case 'D':
601           deterministic = true;
602           break;
603         case 'U':
604           deterministic = false;
605           break;
606 	case OPTION_PLUGIN:
607 #if BFD_SUPPORTS_PLUGINS
608 	  bfd_plugin_set_plugin (optarg);
609 #else
610 	  fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
611 	  xexit (1);
612 #endif
613 	  break;
614 	case OPTION_TARGET:
615 	  target = optarg;
616 	  break;
617 	case OPTION_OUTPUT:
618 	  output_dir = optarg;
619 	  break;
620 	case 0:		/* A long option that just sets a flag.  */
621 	  break;
622         default:
623           usage (0);
624         }
625     }
626 
627   /* PR 13256: Allow for the possibility that the first command line option
628      started with a dash (eg --plugin) but then the following option(s) are
629      old style, non-dash-prefixed versions.  */
630   if (operation == none && write_armap != 1 && !mri_mode
631       && optind > 0 && optind < argc)
632     {
633       argv += (optind - 1);
634       argc -= (optind - 1);
635       optind = 0;
636       goto restart;
637     }
638 
639   return &argv[optind];
640 }
641 
642 /* If neither -D nor -U was specified explicitly,
643    then use the configured default.  */
644 static void
645 default_deterministic (void)
646 {
647   if (deterministic < 0)
648     deterministic = DEFAULT_AR_DETERMINISTIC;
649 }
650 
651 static void
652 ranlib_main (int argc, char **argv)
653 {
654   int arg_index, status = 0;
655   bool touch = false;
656   int c;
657 
658   while ((c = getopt_long (argc, argv, "DhHUvVt", long_options, NULL)) != EOF)
659     {
660       switch (c)
661         {
662 	case 'D':
663 	  deterministic = true;
664 	  break;
665         case 'U':
666           deterministic = false;
667           break;
668 	case 'h':
669 	case 'H':
670 	  show_help = 1;
671 	  break;
672 	case 't':
673 	  touch = true;
674 	  break;
675 	case 'v':
676 	case 'V':
677 	  show_version = 1;
678 	  break;
679 
680 	  /* PR binutils/13493: Support plugins.  */
681 	case OPTION_PLUGIN:
682 #if BFD_SUPPORTS_PLUGINS
683 	  bfd_plugin_set_plugin (optarg);
684 #else
685 	  fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
686 	  xexit (1);
687 #endif
688 	  break;
689 	}
690     }
691 
692   if (argc < 2)
693     ranlib_usage (0);
694 
695   if (show_help)
696     ranlib_usage (1);
697 
698   if (show_version)
699     print_version ("ranlib");
700 
701   default_deterministic ();
702 
703   arg_index = optind;
704 
705   while (arg_index < argc)
706     {
707       if (! touch)
708         status |= ranlib_only (argv[arg_index]);
709       else
710         status |= ranlib_touch (argv[arg_index]);
711       ++arg_index;
712     }
713 
714   xexit (status);
715 }
716 
717 int main (int, char **);
718 
719 int
720 main (int argc, char **argv)
721 {
722   int arg_index;
723   char **files;
724   int file_count;
725   char *inarch_filename;
726   int i;
727 
728 #ifdef HAVE_LC_MESSAGES
729   setlocale (LC_MESSAGES, "");
730 #endif
731   setlocale (LC_CTYPE, "");
732   bindtextdomain (PACKAGE, LOCALEDIR);
733   textdomain (PACKAGE);
734 
735   program_name = argv[0];
736   xmalloc_set_program_name (program_name);
737   bfd_set_error_program_name (program_name);
738 #if BFD_SUPPORTS_PLUGINS
739   bfd_plugin_set_program_name (program_name);
740 #endif
741 
742   expandargv (&argc, &argv);
743 
744   if (is_ranlib < 0)
745     {
746       const char *temp = lbasename (program_name);
747 
748       if (strlen (temp) >= 6
749 	  && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
750 	is_ranlib = 1;
751       else
752 	is_ranlib = 0;
753     }
754 
755   START_PROGRESS (program_name, 0);
756 
757   if (bfd_init () != BFD_INIT_MAGIC)
758     fatal (_("fatal error: libbfd ABI mismatch"));
759   set_default_bfd_target ();
760 
761   xatexit (remove_output);
762 
763   for (i = 1; i < argc; i++)
764     if (! ar_emul_parse_arg (argv[i]))
765       break;
766   argv += (i - 1);
767   argc -= (i - 1);
768 
769   if (is_ranlib)
770     ranlib_main (argc, argv);
771 
772   if (argc < 2)
773     usage (0);
774 
775   argv = decode_options (argc, argv);
776 
777   if (show_help)
778     usage (1);
779 
780   if (show_version)
781     print_version ("ar");
782 
783   arg_index = 0;
784 
785   if (mri_mode)
786     {
787       default_deterministic ();
788       mri_emul ();
789     }
790   else
791     {
792       bfd *arch;
793 
794       /* Fail if no files are specified on the command line.
795 	 (But not for MRI mode which allows for reading arguments
796 	 and filenames from stdin).  */
797       if (argv[arg_index] == NULL)
798 	usage (0);
799 
800       /* We don't use do_quick_append any more.  Too many systems
801 	 expect ar to always rebuild the symbol table even when q is
802 	 used.  */
803 
804       /* We can't write an armap when using ar q, so just do ar r
805          instead.  */
806       if (operation == quick_append && write_armap)
807 	operation = replace;
808 
809       if ((operation == none || operation == print_table)
810 	  && write_armap == 1)
811 	xexit (ranlib_only (argv[arg_index]));
812 
813       if (operation == none)
814 	fatal (_("no operation specified"));
815 
816       if (newer_only && operation != replace)
817 	fatal (_("`u' is only meaningful with the `r' option."));
818 
819       if (newer_only && deterministic > 0)
820         fatal (_("`u' is not meaningful with the `D' option."));
821 
822       if (newer_only && deterministic < 0 && DEFAULT_AR_DETERMINISTIC)
823         non_fatal (_("\
824 `u' modifier ignored since `D' is the default (see `U')"));
825 
826       default_deterministic ();
827 
828       if (postype != pos_default)
829 	{
830 	  posname = argv[arg_index++];
831 	  if (posname == NULL)
832 	    fatal (_("missing position arg."));
833 	}
834 
835       if (counted_name_mode)
836 	{
837 	  if (operation != extract && operation != del)
838 	    fatal (_("`N' is only meaningful with the `x' and `d' options."));
839 	  if (argv[arg_index] == NULL)
840 	    fatal (_("`N' missing value."));
841 	  counted_name_counter = atoi (argv[arg_index++]);
842 	  if (counted_name_counter <= 0)
843 	    fatal (_("Value for `N' must be positive."));
844 	}
845 
846       inarch_filename = argv[arg_index++];
847       if (inarch_filename == NULL)
848 	usage (0);
849 
850       for (file_count = 0; argv[arg_index + file_count] != NULL; file_count++)
851 	continue;
852 
853       files = (file_count > 0) ? argv + arg_index : NULL;
854 
855       arch = open_inarch (inarch_filename,
856 			  files == NULL ? (char *) NULL : files[0]);
857 
858       if (operation == extract && bfd_is_thin_archive (arch))
859 	fatal (_("`x' cannot be used on thin archives."));
860 
861       if (libdeps != NULL)
862 	{
863 	  char **new_files;
864 	  bfd_size_type reclen = strlen (libdeps) + 1;
865 
866 	  /* Create a bfd to contain the dependencies.
867 	     It inherits its type from arch, but we must set the type to
868 	     "binary" otherwise bfd_bwrite() will fail.  After writing, we
869 	     must set the type back to default otherwise adding it to the
870 	     archive will fail.  */
871 	  libdeps_bfd = bfd_create (LIBDEPS, arch);
872 	  if (libdeps_bfd == NULL)
873 	    fatal (_("Cannot create libdeps record."));
874 
875 	  if (bfd_find_target ("binary", libdeps_bfd) == NULL)
876 	    fatal (_("Cannot set libdeps record type to binary."));
877 
878 	  if (! bfd_set_format (libdeps_bfd, bfd_object))
879 	    fatal (_("Cannot set libdeps object format."));
880 
881 	  if (! bfd_make_writable (libdeps_bfd))
882 	    fatal (_("Cannot make libdeps object writable."));
883 
884 	  if (bfd_bwrite (libdeps, reclen, libdeps_bfd) != reclen)
885 	    fatal (_("Cannot write libdeps record."));
886 
887 	  if (! bfd_make_readable (libdeps_bfd))
888 	    fatal (_("Cannot make libdeps object readable."));
889 
890 	  if (bfd_find_target (plugin_target, libdeps_bfd) == NULL)
891 	    fatal (_("Cannot reset libdeps record type."));
892 
893 	  /* Insert our libdeps record in 2nd slot of the list of files
894 	     being operated on.  We shouldn't use 1st slot, but we want
895 	     to avoid having to search all the way to the end of an
896 	     archive with a large number of members at link time.  */
897 	  new_files = xmalloc ((file_count + 2) * sizeof (*new_files));
898 	  if (file_count)
899 	    {
900 	      new_files[0] = files[0];
901 	      memcpy (new_files + 1, files, file_count * sizeof (*files));
902 	    }
903 	  new_files[file_count != 0] = LIBDEPS;
904 	  file_count++;
905 	  new_files[file_count] = NULL;
906 	  files = new_files;
907 	}
908 
909       switch (operation)
910 	{
911 	case print_table:
912 	  map_over_members (arch, print_descr, files, file_count);
913 	  break;
914 
915 	case print_files:
916 	  map_over_members (arch, print_contents, files, file_count);
917 	  break;
918 
919 	case extract:
920 	  map_over_members (arch, extract_file, files, file_count);
921 	  break;
922 
923 	case del:
924 	  if (files != NULL)
925 	    delete_members (arch, files);
926 	  else
927 	    output_filename = NULL;
928 	  break;
929 
930 	case move:
931 	  /* PR 12558: Creating and moving at the same time does
932 	     not make sense.  Just create the archive instead.  */
933 	  if (! silent_create)
934 	    {
935 	      if (files != NULL)
936 		move_members (arch, files);
937 	      else
938 		output_filename = NULL;
939 	      break;
940 	    }
941 	  /* Fall through.  */
942 
943 	case replace:
944 	case quick_append:
945 	  if (files != NULL || write_armap > 0)
946 	    replace_members (arch, files, operation == quick_append);
947 	  else
948 	    output_filename = NULL;
949 	  break;
950 
951 	  /* Shouldn't happen! */
952 	default:
953 	  /* xgettext:c-format */
954 	  fatal (_("internal error -- this option not implemented"));
955 	}
956     }
957 
958   END_PROGRESS (program_name);
959 
960   xexit (0);
961   return 0;
962 }
963 
964 bfd *
965 open_inarch (const char *archive_filename, const char *file)
966 {
967   bfd **last_one;
968   bfd *next_one;
969   struct stat sbuf;
970   bfd *arch;
971   char **matching;
972 
973   bfd_set_error (bfd_error_no_error);
974 
975   if (target == NULL)
976     target = plugin_target;
977 
978   if (stat (archive_filename, &sbuf) != 0)
979     {
980 #if !defined(__GO32__) || defined(__DJGPP__)
981 
982       /* FIXME: I don't understand why this fragment was ifndef'ed
983 	 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
984 	 stat() works just fine in v2.x, so I think this should be
985 	 removed.  For now, I enable it for DJGPP v2. -- EZ.  */
986 
987       /* KLUDGE ALERT! Temporary fix until I figger why
988 	 stat() is wrong ... think it's buried in GO32's IDT - Jax */
989       if (errno != ENOENT)
990 	bfd_fatal (archive_filename);
991 #endif
992 
993       if (!operation_alters_arch)
994 	{
995 	  fprintf (stderr, "%s: ", program_name);
996 	  perror (archive_filename);
997 	  maybequit ();
998 	  return NULL;
999 	}
1000 
1001       /* If the target isn't set, try to figure out the target to use
1002 	 for the archive from the first object on the list.  */
1003       if (target == NULL && file != NULL)
1004 	{
1005 	  bfd *obj;
1006 
1007 	  obj = bfd_openr (file, target);
1008 	  if (obj != NULL)
1009 	    {
1010 	      if (bfd_check_format (obj, bfd_object))
1011 		target = bfd_get_target (obj);
1012 	      (void) bfd_close (obj);
1013 	    }
1014 	}
1015 
1016       /* Create an empty archive.  */
1017       arch = bfd_openw (archive_filename, target);
1018       if (arch == NULL
1019 	  || ! bfd_set_format (arch, bfd_archive)
1020 	  || ! bfd_close (arch))
1021 	bfd_fatal (archive_filename);
1022       else if (!silent_create)
1023         non_fatal (_("creating %s"), archive_filename);
1024 
1025       /* If we die creating a new archive, don't leave it around.  */
1026       output_filename = archive_filename;
1027     }
1028 
1029   arch = bfd_openr (archive_filename, target);
1030   if (arch == NULL)
1031     {
1032     bloser:
1033       bfd_fatal (archive_filename);
1034     }
1035 
1036   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1037     {
1038       bfd_nonfatal (archive_filename);
1039       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1040 	list_matching_formats (matching);
1041       xexit (1);
1042     }
1043 
1044   if ((operation == replace || operation == quick_append)
1045       && bfd_openr_next_archived_file (arch, NULL) != NULL)
1046     {
1047       /* PR 15140: Catch attempts to convert a normal
1048 	 archive into a thin archive or vice versa.  */
1049       if (make_thin_archive && ! bfd_is_thin_archive (arch))
1050 	{
1051 	  fatal (_("Cannot convert existing library %s to thin format"),
1052 		 bfd_get_filename (arch));
1053 	  goto bloser;
1054 	}
1055       else if (! make_thin_archive && bfd_is_thin_archive (arch))
1056 	{
1057 	  fatal (_("Cannot convert existing thin library %s to normal format"),
1058 		 bfd_get_filename (arch));
1059 	  goto bloser;
1060 	}
1061     }
1062 
1063   last_one = &(arch->archive_next);
1064   /* Read all the contents right away, regardless.  */
1065   for (next_one = bfd_openr_next_archived_file (arch, NULL);
1066        next_one;
1067        next_one = bfd_openr_next_archived_file (arch, next_one))
1068     {
1069       PROGRESS (1);
1070       *last_one = next_one;
1071       last_one = &next_one->archive_next;
1072     }
1073   *last_one = (bfd *) NULL;
1074   if (bfd_get_error () != bfd_error_no_more_archived_files)
1075     goto bloser;
1076   return arch;
1077 }
1078 
1079 static void
1080 print_contents (bfd *abfd)
1081 {
1082   bfd_size_type ncopied = 0;
1083   bfd_size_type size;
1084   char *cbuf = (char *) xmalloc (BUFSIZE);
1085   struct stat buf;
1086 
1087   if (bfd_stat_arch_elt (abfd, &buf) != 0)
1088     /* xgettext:c-format */
1089     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
1090 
1091   if (verbose)
1092     printf ("\n<%s>\n\n", bfd_get_filename (abfd));
1093 
1094   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
1095 
1096   size = buf.st_size;
1097   while (ncopied < size)
1098     {
1099       bfd_size_type nread;
1100       bfd_size_type tocopy = size - ncopied;
1101 
1102       if (tocopy > BUFSIZE)
1103 	tocopy = BUFSIZE;
1104 
1105       nread = bfd_bread (cbuf, tocopy, abfd);
1106       if (nread != tocopy)
1107 	/* xgettext:c-format */
1108 	fatal (_("%s is not a valid archive"),
1109 	       bfd_get_filename (abfd->my_archive));
1110 
1111       /* fwrite in mingw32 may return int instead of bfd_size_type. Cast the
1112 	 return value to bfd_size_type to avoid comparison between signed and
1113 	 unsigned values.  */
1114       if ((bfd_size_type) fwrite (cbuf, 1, nread, stdout) != nread)
1115 	fatal ("stdout: %s", strerror (errno));
1116       ncopied += tocopy;
1117     }
1118   free (cbuf);
1119 }
1120 
1121 
1122 static FILE * open_output_file (bfd *) ATTRIBUTE_RETURNS_NONNULL;
1123 
1124 static FILE *
1125 open_output_file (bfd * abfd)
1126 {
1127   output_filename = bfd_get_filename (abfd);
1128 
1129   /* PR binutils/17533: Do not allow directory traversal
1130      outside of the current directory tree - unless the
1131      user has explicitly specified an output directory.  */
1132   if (! is_valid_archive_path (output_filename))
1133     {
1134       char * base = (char *) lbasename (output_filename);
1135 
1136       non_fatal (_("illegal output pathname for archive member: %s, using '%s' instead"),
1137 		 output_filename, base);
1138       output_filename = base;
1139     }
1140 
1141   if (output_dir)
1142     {
1143       size_t len = strlen (output_dir);
1144 
1145       if (len > 0)
1146 	{
1147 	  /* FIXME: There is a memory leak here, but it is not serious.  */
1148 	  if (IS_DIR_SEPARATOR (output_dir [len - 1]))
1149 	    output_filename = concat (output_dir, output_filename, NULL);
1150 	  else
1151 	    output_filename = concat (output_dir, "/", output_filename, NULL);
1152 	}
1153     }
1154 
1155   if (verbose)
1156     printf ("x - %s\n", output_filename);
1157 
1158   FILE * ostream = fopen (output_filename, FOPEN_WB);
1159   if (ostream == NULL)
1160     {
1161       perror (output_filename);
1162       xexit (1);
1163     }
1164 
1165   return ostream;
1166 }
1167 
1168 /* Extract a member of the archive into its own file.
1169 
1170    We defer opening the new file until after we have read a BUFSIZ chunk of the
1171    old one, since we know we have just read the archive header for the old
1172    one.  Since most members are shorter than BUFSIZ, this means we will read
1173    the old header, read the old data, write a new inode for the new file, and
1174    write the new data, and be done. This 'optimization' is what comes from
1175    sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
1176    Gilmore  */
1177 
1178 void
1179 extract_file (bfd *abfd)
1180 {
1181   bfd_size_type size;
1182   struct stat buf;
1183 
1184   if (preserve_dates)
1185     memset (&buf, 0, sizeof (buf));
1186 
1187   if (bfd_stat_arch_elt (abfd, &buf) != 0)
1188     /* xgettext:c-format */
1189     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
1190   size = buf.st_size;
1191 
1192   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
1193 
1194   output_file = NULL;
1195   if (size == 0)
1196     {
1197       output_file = open_output_file (abfd);
1198     }
1199   else
1200     {
1201       bfd_size_type ncopied = 0;
1202       char *cbuf = (char *) xmalloc (BUFSIZE);
1203 
1204       while (ncopied < size)
1205 	{
1206 	  bfd_size_type nread, tocopy;
1207 
1208 	  tocopy = size - ncopied;
1209 	  if (tocopy > BUFSIZE)
1210 	    tocopy = BUFSIZE;
1211 
1212 	  nread = bfd_bread (cbuf, tocopy, abfd);
1213 	  if (nread != tocopy)
1214 	    /* xgettext:c-format */
1215 	    fatal (_("%s is not a valid archive"),
1216 		   bfd_get_filename (abfd->my_archive));
1217 
1218 	  /* See comment above; this saves disk arm motion.  */
1219 	  if (output_file == NULL)
1220 	    output_file = open_output_file (abfd);
1221 
1222 	  /* fwrite in mingw32 may return int instead of bfd_size_type. Cast
1223 	     the return value to bfd_size_type to avoid comparison between
1224 	     signed and unsigned values.  */
1225 	  if ((bfd_size_type) fwrite (cbuf, 1, nread, output_file) != nread)
1226 	    fatal ("%s: %s", output_filename, strerror (errno));
1227 
1228 	  ncopied += tocopy;
1229 	}
1230 
1231       free (cbuf);
1232     }
1233 
1234   fclose (output_file);
1235 
1236   output_file = NULL;
1237 
1238   chmod (output_filename, buf.st_mode);
1239 
1240   if (preserve_dates)
1241     {
1242       /* Set access time to modification time.  Only st_mtime is
1243 	 initialized by bfd_stat_arch_elt.  */
1244       buf.st_atime = buf.st_mtime;
1245       set_times (output_filename, &buf);
1246     }
1247 
1248   output_filename = NULL;
1249 }
1250 
1251 static void
1252 write_archive (bfd *iarch)
1253 {
1254   bfd *obfd;
1255   char *old_name, *new_name;
1256   bfd *contents_head = iarch->archive_next;
1257   int tmpfd = -1;
1258 
1259   old_name = xstrdup (bfd_get_filename (iarch));
1260   new_name = make_tempname (old_name, &tmpfd);
1261 
1262   if (new_name == NULL)
1263     bfd_fatal (_("could not create temporary file whilst writing archive"));
1264 
1265   output_filename = new_name;
1266 
1267   obfd = bfd_fdopenw (new_name, bfd_get_target (iarch), tmpfd);
1268 
1269   if (obfd == NULL)
1270     {
1271       close (tmpfd);
1272       bfd_fatal (old_name);
1273     }
1274 
1275   output_bfd = obfd;
1276 
1277   bfd_set_format (obfd, bfd_archive);
1278 
1279   /* Request writing the archive symbol table unless we've
1280      been explicitly requested not to.  */
1281   obfd->has_armap = write_armap >= 0;
1282 
1283   if (ar_truncate)
1284     {
1285       /* This should really use bfd_set_file_flags, but that rejects
1286          archives.  */
1287       obfd->flags |= BFD_TRADITIONAL_FORMAT;
1288     }
1289 
1290   if (deterministic)
1291     obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1292 
1293   if (full_pathname)
1294     obfd->flags |= BFD_ARCHIVE_FULL_PATH;
1295 
1296   if (make_thin_archive || bfd_is_thin_archive (iarch))
1297     bfd_set_thin_archive (obfd, true);
1298 
1299   if (!bfd_set_archive_head (obfd, contents_head))
1300     bfd_fatal (old_name);
1301 
1302   tmpfd = dup (tmpfd);
1303   if (!bfd_close (obfd))
1304     bfd_fatal (old_name);
1305 
1306   output_bfd = NULL;
1307   output_filename = NULL;
1308 
1309   /* We don't care if this fails; we might be creating the archive.  */
1310   bfd_close (iarch);
1311 
1312   if (smart_rename (new_name, old_name, tmpfd, NULL, false) != 0)
1313     xexit (1);
1314   free (old_name);
1315   free (new_name);
1316 }
1317 
1318 /* Return a pointer to the pointer to the entry which should be rplacd'd
1319    into when altering.  DEFAULT_POS should be how to interpret pos_default,
1320    and should be a pos value.  */
1321 
1322 static bfd **
1323 get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1324 {
1325   bfd **after_bfd = contents;
1326   enum pos realpos;
1327   const char *realposname;
1328 
1329   if (postype == pos_default)
1330     {
1331       realpos = default_pos;
1332       realposname = default_posname;
1333     }
1334   else
1335     {
1336       realpos = postype;
1337       realposname = posname;
1338     }
1339 
1340   if (realpos == pos_end)
1341     {
1342       while (*after_bfd)
1343 	after_bfd = &((*after_bfd)->archive_next);
1344     }
1345   else
1346     {
1347       for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
1348 	if (FILENAME_CMP (bfd_get_filename (*after_bfd), realposname) == 0)
1349 	  {
1350 	    if (realpos == pos_after)
1351 	      after_bfd = &(*after_bfd)->archive_next;
1352 	    break;
1353 	  }
1354     }
1355   return after_bfd;
1356 }
1357 
1358 static void
1359 delete_members (bfd *arch, char **files_to_delete)
1360 {
1361   bfd **current_ptr_ptr;
1362   bool found;
1363   bool something_changed = false;
1364   int match_count;
1365 
1366   for (; *files_to_delete != NULL; ++files_to_delete)
1367     {
1368       /* In a.out systems, the armap is optional.  It's also called
1369 	 __.SYMDEF.  So if the user asked to delete it, we should remember
1370 	 that fact. This isn't quite right for COFF systems (where
1371 	 __.SYMDEF might be regular member), but it's very unlikely
1372 	 to be a problem.  FIXME */
1373 
1374       if (!strcmp (*files_to_delete, "__.SYMDEF"))
1375 	{
1376 	  arch->has_armap = false;
1377 	  write_armap = -1;
1378 	  continue;
1379 	}
1380 
1381       found = false;
1382       match_count = 0;
1383       current_ptr_ptr = &(arch->archive_next);
1384       while (*current_ptr_ptr)
1385 	{
1386 	  if (FILENAME_CMP (normalize (*files_to_delete, arch),
1387 			    bfd_get_filename (*current_ptr_ptr)) == 0)
1388 	    {
1389 	      ++match_count;
1390 	      if (counted_name_mode
1391 		  && match_count != counted_name_counter)
1392 		{
1393 		  /* Counting, and didn't match on count; go on to the
1394                      next one.  */
1395 		}
1396 	      else
1397 		{
1398 		  found = true;
1399 		  something_changed = true;
1400 		  if (verbose)
1401 		    printf ("d - %s\n",
1402 			    *files_to_delete);
1403 		  *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
1404 		  goto next_file;
1405 		}
1406 	    }
1407 
1408 	  current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1409 	}
1410 
1411       if (verbose && !found)
1412 	{
1413 	  /* xgettext:c-format */
1414 	  printf (_("No member named `%s'\n"), *files_to_delete);
1415 	}
1416     next_file:
1417       ;
1418     }
1419 
1420   if (something_changed)
1421     write_archive (arch);
1422   else
1423     output_filename = NULL;
1424 }
1425 
1426 
1427 /* Reposition existing members within an archive */
1428 
1429 static void
1430 move_members (bfd *arch, char **files_to_move)
1431 {
1432   bfd **after_bfd;		/* New entries go after this one */
1433   bfd **current_ptr_ptr;	/* cdr pointer into contents */
1434 
1435   for (; *files_to_move; ++files_to_move)
1436     {
1437       current_ptr_ptr = &(arch->archive_next);
1438       while (*current_ptr_ptr)
1439 	{
1440 	  bfd *current_ptr = *current_ptr_ptr;
1441 	  if (FILENAME_CMP (normalize (*files_to_move, arch),
1442 			    bfd_get_filename (current_ptr)) == 0)
1443 	    {
1444 	      /* Move this file to the end of the list - first cut from
1445 		 where it is.  */
1446 	      bfd *link_bfd;
1447 	      *current_ptr_ptr = current_ptr->archive_next;
1448 
1449 	      /* Now glue to end */
1450 	      after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1451 	      link_bfd = *after_bfd;
1452 	      *after_bfd = current_ptr;
1453 	      current_ptr->archive_next = link_bfd;
1454 
1455 	      if (verbose)
1456 		printf ("m - %s\n", *files_to_move);
1457 
1458 	      goto next_file;
1459 	    }
1460 
1461 	  current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1462 	}
1463       /* xgettext:c-format */
1464       fatal (_("no entry %s in archive %s!"), *files_to_move,
1465 	     bfd_get_filename (arch));
1466 
1467     next_file:;
1468     }
1469 
1470   write_archive (arch);
1471 }
1472 
1473 /* Ought to default to replacing in place, but this is existing practice!  */
1474 
1475 static void
1476 replace_members (bfd *arch, char **files_to_move, bool quick)
1477 {
1478   bool changed = false;
1479   bfd **after_bfd;		/* New entries go after this one.  */
1480   bfd *current;
1481   bfd **current_ptr;
1482 
1483   while (files_to_move && *files_to_move)
1484     {
1485       if (! quick)
1486 	{
1487 	  current_ptr = &arch->archive_next;
1488 	  while (*current_ptr)
1489 	    {
1490 	      current = *current_ptr;
1491 
1492 	      /* For compatibility with existing ar programs, we
1493 		 permit the same file to be added multiple times.  */
1494 	      if (FILENAME_CMP (normalize (*files_to_move, arch),
1495 				normalize (bfd_get_filename (current), arch)) == 0
1496 		  && current->arelt_data != NULL)
1497 		{
1498 		  bool replaced;
1499 		  if (newer_only)
1500 		    {
1501 		      struct stat fsbuf, asbuf;
1502 
1503 		      if (stat (*files_to_move, &fsbuf) != 0)
1504 			{
1505 			  if (errno != ENOENT)
1506 			    bfd_fatal (*files_to_move);
1507 			  goto next_file;
1508 			}
1509 		      if (bfd_stat_arch_elt (current, &asbuf) != 0)
1510 			/* xgettext:c-format */
1511 			fatal (_("internal stat error on %s"),
1512 			       bfd_get_filename (current));
1513 
1514 		      if (fsbuf.st_mtime <= asbuf.st_mtime)
1515 			goto next_file;
1516 		    }
1517 
1518 		  after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
1519 					   bfd_get_filename (current));
1520 		  if (libdeps_bfd != NULL
1521 		      && FILENAME_CMP (normalize (*files_to_move, arch),
1522 				       LIBDEPS) == 0)
1523 		    {
1524 		      replaced = ar_emul_replace_bfd (after_bfd, libdeps_bfd,
1525 						      verbose);
1526 		    }
1527 		  else
1528 		    {
1529 		      replaced = ar_emul_replace (after_bfd, *files_to_move,
1530 						  target, verbose);
1531 		    }
1532 		  if (replaced)
1533 		    {
1534 		      /* Snip out this entry from the chain.  */
1535 		      *current_ptr = (*current_ptr)->archive_next;
1536 		      changed = true;
1537 		    }
1538 
1539 		  goto next_file;
1540 		}
1541 	      current_ptr = &(current->archive_next);
1542 	    }
1543 	}
1544 
1545       /* Add to the end of the archive.  */
1546       after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1547 
1548       if (libdeps_bfd != NULL
1549 	  && FILENAME_CMP (normalize (*files_to_move, arch), LIBDEPS) == 0)
1550         {
1551 	  changed |= ar_emul_append_bfd (after_bfd, libdeps_bfd,
1552 					 verbose, make_thin_archive);
1553 	}
1554       else
1555         {
1556 	  changed |= ar_emul_append (after_bfd, *files_to_move, target,
1557 				     verbose, make_thin_archive);
1558 	}
1559 
1560     next_file:;
1561 
1562       files_to_move++;
1563     }
1564 
1565   if (changed)
1566     write_archive (arch);
1567   else
1568     output_filename = NULL;
1569 }
1570 
1571 static int
1572 ranlib_only (const char *archname)
1573 {
1574   bfd *arch;
1575 
1576   if (get_file_size (archname) < 1)
1577     return 1;
1578   write_armap = 1;
1579   arch = open_inarch (archname, (char *) NULL);
1580   if (arch == NULL)
1581     xexit (1);
1582   write_archive (arch);
1583   return 0;
1584 }
1585 
1586 /* Update the timestamp of the symbol map of an archive.  */
1587 
1588 static int
1589 ranlib_touch (const char *archname)
1590 {
1591 #ifdef __GO32__
1592   /* I don't think updating works on go32.  */
1593   ranlib_only (archname);
1594 #else
1595   int f;
1596   bfd *arch;
1597   char **matching;
1598 
1599   if (get_file_size (archname) < 1)
1600     return 1;
1601   f = open (archname, O_RDWR | O_BINARY, 0);
1602   if (f < 0)
1603     {
1604       bfd_set_error (bfd_error_system_call);
1605       bfd_fatal (archname);
1606     }
1607 
1608   arch = bfd_fdopenr (archname, (const char *) NULL, f);
1609   if (arch == NULL)
1610     bfd_fatal (archname);
1611   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1612     {
1613       bfd_nonfatal (archname);
1614       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1615 	list_matching_formats (matching);
1616       xexit (1);
1617     }
1618 
1619   if (! bfd_has_map (arch))
1620     /* xgettext:c-format */
1621     fatal (_("%s: no archive map to update"), archname);
1622 
1623   if (deterministic)
1624     arch->flags |= BFD_DETERMINISTIC_OUTPUT;
1625 
1626   bfd_update_armap_timestamp (arch);
1627 
1628   if (! bfd_close (arch))
1629     bfd_fatal (archname);
1630 #endif
1631   return 0;
1632 }
1633 
1634 /* Things which are interesting to map over all or some of the files: */
1635 
1636 static void
1637 print_descr (bfd *abfd)
1638 {
1639   print_arelt_descr (stdout, abfd, verbose, display_offsets);
1640 }
1641