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