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