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