]> Git Repo - binutils.git/blob - binutils/ar.c
PR28391, strip/objcopy --preserve-dates *.a: cannot set time
[binutils.git] / binutils / ar.c
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 \f
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 \f
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
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
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 \f
278 bool operation_alters_arch = false;
279
280 static void
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
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 *
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
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 **
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
643 default_deterministic (void)
644 {
645   if (deterministic < 0)
646     deterministic = DEFAULT_AR_DETERMINISTIC;
647 }
648
649 static void
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
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 *
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
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 *
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
1178 extract_file (bfd *abfd)
1179 {
1180   bfd_size_type size;
1181   struct stat buf;
1182
1183   if (preserve_dates)
1184     memset (&buf, 0, sizeof (buf));
1185
1186   if (bfd_stat_arch_elt (abfd, &buf) != 0)
1187     /* xgettext:c-format */
1188     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
1189   size = buf.st_size;
1190
1191   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
1192
1193   output_file = NULL;
1194   if (size == 0)
1195     {
1196       output_file = open_output_file (abfd);
1197     }
1198   else
1199     {
1200       bfd_size_type ncopied = 0;
1201       char *cbuf = (char *) xmalloc (BUFSIZE);
1202
1203       while (ncopied < size)
1204         {
1205           bfd_size_type nread, tocopy;
1206
1207           tocopy = size - ncopied;
1208           if (tocopy > BUFSIZE)
1209             tocopy = BUFSIZE;
1210
1211           nread = bfd_bread (cbuf, tocopy, abfd);
1212           if (nread != tocopy)
1213             /* xgettext:c-format */
1214             fatal (_("%s is not a valid archive"),
1215                    bfd_get_filename (abfd->my_archive));
1216
1217           /* See comment above; this saves disk arm motion.  */
1218           if (output_file == NULL)
1219             output_file = open_output_file (abfd);
1220
1221           /* fwrite in mingw32 may return int instead of bfd_size_type. Cast
1222              the return value to bfd_size_type to avoid comparison between
1223              signed and unsigned values.  */
1224           if ((bfd_size_type) fwrite (cbuf, 1, nread, output_file) != nread)
1225             fatal ("%s: %s", output_filename, strerror (errno));
1226
1227           ncopied += tocopy;
1228         }
1229
1230       free (cbuf);
1231     }
1232
1233   fclose (output_file);
1234
1235   output_file = NULL;
1236
1237   chmod (output_filename, buf.st_mode);
1238
1239   if (preserve_dates)
1240     {
1241       /* Set access time to modification time.  Only st_mtime is
1242          initialized by bfd_stat_arch_elt.  */
1243       buf.st_atime = buf.st_mtime;
1244       set_times (output_filename, &buf);
1245     }
1246
1247   output_filename = NULL;
1248 }
1249
1250 static void
1251 write_archive (bfd *iarch)
1252 {
1253   bfd *obfd;
1254   char *old_name, *new_name;
1255   bfd *contents_head = iarch->archive_next;
1256   int tmpfd = -1;
1257
1258   old_name = xstrdup (bfd_get_filename (iarch));
1259   new_name = make_tempname (old_name, &tmpfd);
1260
1261   if (new_name == NULL)
1262     bfd_fatal (_("could not create temporary file whilst writing archive"));
1263
1264   output_filename = new_name;
1265
1266   obfd = bfd_fdopenw (new_name, bfd_get_target (iarch), tmpfd);
1267
1268   if (obfd == NULL)
1269     {
1270       close (tmpfd);
1271       bfd_fatal (old_name);
1272     }
1273
1274   output_bfd = obfd;
1275
1276   bfd_set_format (obfd, bfd_archive);
1277
1278   /* Request writing the archive symbol table unless we've
1279      been explicitly requested not to.  */
1280   obfd->has_armap = write_armap >= 0;
1281
1282   if (ar_truncate)
1283     {
1284       /* This should really use bfd_set_file_flags, but that rejects
1285          archives.  */
1286       obfd->flags |= BFD_TRADITIONAL_FORMAT;
1287     }
1288
1289   if (deterministic)
1290     obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1291
1292   if (full_pathname)
1293     obfd->flags |= BFD_ARCHIVE_FULL_PATH;
1294
1295   if (make_thin_archive || bfd_is_thin_archive (iarch))
1296     bfd_set_thin_archive (obfd, true);
1297
1298   if (!bfd_set_archive_head (obfd, contents_head))
1299     bfd_fatal (old_name);
1300
1301   tmpfd = dup (tmpfd);
1302   if (!bfd_close (obfd))
1303     bfd_fatal (old_name);
1304
1305   output_bfd = NULL;
1306   output_filename = NULL;
1307
1308   /* We don't care if this fails; we might be creating the archive.  */
1309   bfd_close (iarch);
1310
1311   if (smart_rename (new_name, old_name, tmpfd, NULL, false) != 0)
1312     xexit (1);
1313   free (old_name);
1314   free (new_name);
1315 }
1316
1317 /* Return a pointer to the pointer to the entry which should be rplacd'd
1318    into when altering.  DEFAULT_POS should be how to interpret pos_default,
1319    and should be a pos value.  */
1320
1321 static bfd **
1322 get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1323 {
1324   bfd **after_bfd = contents;
1325   enum pos realpos;
1326   const char *realposname;
1327
1328   if (postype == pos_default)
1329     {
1330       realpos = default_pos;
1331       realposname = default_posname;
1332     }
1333   else
1334     {
1335       realpos = postype;
1336       realposname = posname;
1337     }
1338
1339   if (realpos == pos_end)
1340     {
1341       while (*after_bfd)
1342         after_bfd = &((*after_bfd)->archive_next);
1343     }
1344   else
1345     {
1346       for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
1347         if (FILENAME_CMP (bfd_get_filename (*after_bfd), realposname) == 0)
1348           {
1349             if (realpos == pos_after)
1350               after_bfd = &(*after_bfd)->archive_next;
1351             break;
1352           }
1353     }
1354   return after_bfd;
1355 }
1356
1357 static void
1358 delete_members (bfd *arch, char **files_to_delete)
1359 {
1360   bfd **current_ptr_ptr;
1361   bool found;
1362   bool something_changed = false;
1363   int match_count;
1364
1365   for (; *files_to_delete != NULL; ++files_to_delete)
1366     {
1367       /* In a.out systems, the armap is optional.  It's also called
1368          __.SYMDEF.  So if the user asked to delete it, we should remember
1369          that fact. This isn't quite right for COFF systems (where
1370          __.SYMDEF might be regular member), but it's very unlikely
1371          to be a problem.  FIXME */
1372
1373       if (!strcmp (*files_to_delete, "__.SYMDEF"))
1374         {
1375           arch->has_armap = false;
1376           write_armap = -1;
1377           continue;
1378         }
1379
1380       found = false;
1381       match_count = 0;
1382       current_ptr_ptr = &(arch->archive_next);
1383       while (*current_ptr_ptr)
1384         {
1385           if (FILENAME_CMP (normalize (*files_to_delete, arch),
1386                             bfd_get_filename (*current_ptr_ptr)) == 0)
1387             {
1388               ++match_count;
1389               if (counted_name_mode
1390                   && match_count != counted_name_counter)
1391                 {
1392                   /* Counting, and didn't match on count; go on to the
1393                      next one.  */
1394                 }
1395               else
1396                 {
1397                   found = true;
1398                   something_changed = true;
1399                   if (verbose)
1400                     printf ("d - %s\n",
1401                             *files_to_delete);
1402                   *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
1403                   goto next_file;
1404                 }
1405             }
1406
1407           current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1408         }
1409
1410       if (verbose && !found)
1411         {
1412           /* xgettext:c-format */
1413           printf (_("No member named `%s'\n"), *files_to_delete);
1414         }
1415     next_file:
1416       ;
1417     }
1418
1419   if (something_changed)
1420     write_archive (arch);
1421   else
1422     output_filename = NULL;
1423 }
1424
1425
1426 /* Reposition existing members within an archive */
1427
1428 static void
1429 move_members (bfd *arch, char **files_to_move)
1430 {
1431   bfd **after_bfd;              /* New entries go after this one */
1432   bfd **current_ptr_ptr;        /* cdr pointer into contents */
1433
1434   for (; *files_to_move; ++files_to_move)
1435     {
1436       current_ptr_ptr = &(arch->archive_next);
1437       while (*current_ptr_ptr)
1438         {
1439           bfd *current_ptr = *current_ptr_ptr;
1440           if (FILENAME_CMP (normalize (*files_to_move, arch),
1441                             bfd_get_filename (current_ptr)) == 0)
1442             {
1443               /* Move this file to the end of the list - first cut from
1444                  where it is.  */
1445               bfd *link_bfd;
1446               *current_ptr_ptr = current_ptr->archive_next;
1447
1448               /* Now glue to end */
1449               after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1450               link_bfd = *after_bfd;
1451               *after_bfd = current_ptr;
1452               current_ptr->archive_next = link_bfd;
1453
1454               if (verbose)
1455                 printf ("m - %s\n", *files_to_move);
1456
1457               goto next_file;
1458             }
1459
1460           current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1461         }
1462       /* xgettext:c-format */
1463       fatal (_("no entry %s in archive %s!"), *files_to_move,
1464              bfd_get_filename (arch));
1465
1466     next_file:;
1467     }
1468
1469   write_archive (arch);
1470 }
1471
1472 /* Ought to default to replacing in place, but this is existing practice!  */
1473
1474 static void
1475 replace_members (bfd *arch, char **files_to_move, bool quick)
1476 {
1477   bool changed = false;
1478   bfd **after_bfd;              /* New entries go after this one.  */
1479   bfd *current;
1480   bfd **current_ptr;
1481
1482   while (files_to_move && *files_to_move)
1483     {
1484       if (! quick)
1485         {
1486           current_ptr = &arch->archive_next;
1487           while (*current_ptr)
1488             {
1489               current = *current_ptr;
1490
1491               /* For compatibility with existing ar programs, we
1492                  permit the same file to be added multiple times.  */
1493               if (FILENAME_CMP (normalize (*files_to_move, arch),
1494                                 normalize (bfd_get_filename (current), arch)) == 0
1495                   && current->arelt_data != NULL)
1496                 {
1497                   bool replaced;
1498                   if (newer_only)
1499                     {
1500                       struct stat fsbuf, asbuf;
1501
1502                       if (stat (*files_to_move, &fsbuf) != 0)
1503                         {
1504                           if (errno != ENOENT)
1505                             bfd_fatal (*files_to_move);
1506                           goto next_file;
1507                         }
1508                       if (bfd_stat_arch_elt (current, &asbuf) != 0)
1509                         /* xgettext:c-format */
1510                         fatal (_("internal stat error on %s"),
1511                                bfd_get_filename (current));
1512
1513                       if (fsbuf.st_mtime <= asbuf.st_mtime)
1514                         goto next_file;
1515                     }
1516
1517                   after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
1518                                            bfd_get_filename (current));
1519                   if (libdeps_bfd != NULL
1520                       && FILENAME_CMP (normalize (*files_to_move, arch),
1521                                        LIBDEPS) == 0)
1522                     {
1523                       replaced = ar_emul_replace_bfd (after_bfd, libdeps_bfd,
1524                                                       verbose);
1525                     }
1526                   else
1527                     {
1528                       replaced = ar_emul_replace (after_bfd, *files_to_move,
1529                                                   target, verbose);
1530                     }
1531                   if (replaced)
1532                     {
1533                       /* Snip out this entry from the chain.  */
1534                       *current_ptr = (*current_ptr)->archive_next;
1535                       changed = true;
1536                     }
1537
1538                   goto next_file;
1539                 }
1540               current_ptr = &(current->archive_next);
1541             }
1542         }
1543
1544       /* Add to the end of the archive.  */
1545       after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1546
1547       if (libdeps_bfd != NULL
1548           && FILENAME_CMP (normalize (*files_to_move, arch), LIBDEPS) == 0)
1549         {
1550           changed |= ar_emul_append_bfd (after_bfd, libdeps_bfd,
1551                                          verbose, make_thin_archive);
1552         }
1553       else
1554         {
1555           changed |= ar_emul_append (after_bfd, *files_to_move, target,
1556                                      verbose, make_thin_archive);
1557         }
1558
1559     next_file:;
1560
1561       files_to_move++;
1562     }
1563
1564   if (changed)
1565     write_archive (arch);
1566   else
1567     output_filename = NULL;
1568 }
1569
1570 static int
1571 ranlib_only (const char *archname)
1572 {
1573   bfd *arch;
1574
1575   if (get_file_size (archname) < 1)
1576     return 1;
1577   write_armap = 1;
1578   arch = open_inarch (archname, (char *) NULL);
1579   if (arch == NULL)
1580     xexit (1);
1581   write_archive (arch);
1582   return 0;
1583 }
1584
1585 /* Update the timestamp of the symbol map of an archive.  */
1586
1587 static int
1588 ranlib_touch (const char *archname)
1589 {
1590 #ifdef __GO32__
1591   /* I don't think updating works on go32.  */
1592   ranlib_only (archname);
1593 #else
1594   int f;
1595   bfd *arch;
1596   char **matching;
1597
1598   if (get_file_size (archname) < 1)
1599     return 1;
1600   f = open (archname, O_RDWR | O_BINARY, 0);
1601   if (f < 0)
1602     {
1603       bfd_set_error (bfd_error_system_call);
1604       bfd_fatal (archname);
1605     }
1606
1607   arch = bfd_fdopenr (archname, (const char *) NULL, f);
1608   if (arch == NULL)
1609     bfd_fatal (archname);
1610   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1611     {
1612       bfd_nonfatal (archname);
1613       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1614         {
1615           list_matching_formats (matching);
1616           free (matching);
1617         }
1618       xexit (1);
1619     }
1620
1621   if (! bfd_has_map (arch))
1622     /* xgettext:c-format */
1623     fatal (_("%s: no archive map to update"), archname);
1624
1625   if (deterministic)
1626     arch->flags |= BFD_DETERMINISTIC_OUTPUT;
1627
1628   bfd_update_armap_timestamp (arch);
1629
1630   if (! bfd_close (arch))
1631     bfd_fatal (archname);
1632 #endif
1633   return 0;
1634 }
1635
1636 /* Things which are interesting to map over all or some of the files: */
1637
1638 static void
1639 print_descr (bfd *abfd)
1640 {
1641   print_arelt_descr (stdout, abfd, verbose, display_offsets);
1642 }
This page took 0.119072 seconds and 4 git commands to generate.