Remove path name from test case
[binutils-gdb.git] / binutils / ar.c
1 /* ar.c - Archive modify and extract.
2 Copyright (C) 1991-2023 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 "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 \f
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
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 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 \f
274 bool operation_alters_arch = false;
275
276 static void
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
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 *
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
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 **
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
637 default_deterministic (void)
638 {
639 if (deterministic < 0)
640 deterministic = DEFAULT_AR_DETERMINISTIC;
641 }
642
643 static void
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
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 *
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
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 *
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
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
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 **
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
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
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
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
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
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
1645 print_descr (bfd *abfd)
1646 {
1647 print_arelt_descr (stdout, abfd, verbose, display_offsets);
1648 }