]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/ar.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / binutils / ar.c
CommitLineData
252b5132 1/* ar.c - Archive modify and extract.
250d07de 2 Copyright (C) 1991-2021 Free Software Foundation, Inc.
252b5132 3
eb1e0e80 4 This file is part of GNU Binutils.
252b5132 5
eb1e0e80
NC
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
32866df7 8 the Free Software Foundation; either version 3 of the License, or
eb1e0e80 9 (at your option) any later version.
252b5132 10
eb1e0e80
NC
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.
252b5132 15
eb1e0e80
NC
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
32866df7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
252b5132
RH
20\f
21/*
4e407551
AM
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. */
eb1e0e80 25
3db64b00 26#include "sysdep.h"
252b5132 27#include "bfd.h"
365f5fb6 28#include "libbfd.h"
252b5132
RH
29#include "libiberty.h"
30#include "progress.h"
4e407551 31#include "getopt.h"
252b5132 32#include "aout/ar.h"
3db64b00 33#include "bucomm.h"
252b5132 34#include "arsup.h"
5af11cab 35#include "filenames.h"
eb1e0e80 36#include "binemul.h"
7d0b9ebc 37#include "plugin-api.h"
ce3c775b 38#include "plugin.h"
197245e3 39#include "ansidecl.h"
252b5132
RH
40
41#ifdef __GO32___
a8da6403 42#define EXT_NAME_LEN 3 /* Bufflen of addition to name if it's MS-DOS. */
252b5132 43#else
a8da6403 44#define EXT_NAME_LEN 6 /* Ditto for *NIX. */
252b5132
RH
45#endif
46
a8da6403 47/* Static declarations. */
252b5132 48
2da42df6
AJ
49static void mri_emul (void);
50static const char *normalize (const char *, bfd *);
51static void remove_output (void);
52static void map_over_members (bfd *, void (*)(bfd *), char **, int);
53static void print_contents (bfd * member);
54static void delete_members (bfd *, char **files_to_delete);
252b5132 55
2da42df6
AJ
56static void move_members (bfd *, char **files_to_move);
57static void replace_members
58 (bfd *, char **files_to_replace, bfd_boolean quick);
59static void print_descr (bfd * abfd);
60static void write_archive (bfd *);
d68c385b
NC
61static int ranlib_only (const char *archname);
62static int ranlib_touch (const char *archname);
2da42df6 63static void usage (int);
252b5132 64\f
a8da6403 65/** Globals and flags. */
252b5132 66
85b1c36d 67static int mri_mode;
252b5132
RH
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. */
72extern int is_ranlib;
73
74/* Nonzero means don't warn about creating the archive file if necessary. */
75int silent_create = 0;
76
77/* Nonzero means describe each action performed. */
78int verbose = 0;
79
1869e86f
AB
80/* Nonzero means display offsets of files in the archive. */
81int display_offsets = 0;
82
252b5132
RH
83/* Nonzero means preserve dates of members when extracting them. */
84int preserve_dates = 0;
85
86/* Nonzero means don't replace existing members whose dates are more recent
87 than the corresponding files. */
88int 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;
50c2245b 92 +1 means we've been explicitly asked to write it;
252b5132
RH
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. */
97int write_armap = 0;
98
36e4dce6
CD
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. */
9cb80f72 102int deterministic = -1; /* Determinism indeterminate. */
36e4dce6 103
252b5132
RH
104/* Nonzero means it's the name of an existing member; position new or moved
105 files with respect to this one. */
106char *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. */
112enum pos
113 {
114 pos_default, pos_before, pos_after, pos_end
115 } postype = pos_default;
116
4e407551
AM
117enum operations
118 {
119 none = 0, del, replace, print_table,
120 print_files, extract, move, quick_append
121 } operation = none;
122
252b5132 123static bfd **
2da42df6 124get_pos_bfd (bfd **, enum pos, const char *);
252b5132 125
b34976b6 126/* For extract/delete only. If COUNTED_NAME_MODE is TRUE, we only
3de39064 127 extract the COUNTED_NAME_COUNTER instance of that name. */
b34976b6 128static bfd_boolean counted_name_mode = 0;
3de39064
ILT
129static int counted_name_counter = 0;
130
252b5132 131/* Whether to truncate names of files stored in the archive. */
b34976b6 132static bfd_boolean ar_truncate = FALSE;
252b5132 133
fe84ea5d
ILT
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. */
b34976b6 137static bfd_boolean full_pathname = FALSE;
fe84ea5d 138
a8da6403
NC
139/* Whether to create a "thin" archive (symbol index only -- no files). */
140static bfd_boolean make_thin_archive = FALSE;
141
f3016d6c
HC
142#define LIBDEPS "__.LIBDEP"
143/* Text to store in the __.LIBDEP archive element for the linker to use. */
144static char * libdeps = NULL;
145static bfd * libdeps_bfd = NULL;
146
4e407551
AM
147static int show_version = 0;
148
149static int show_help = 0;
150
92b1b678
MT
151#if BFD_SUPPORTS_PLUGINS
152static const char *plugin_target = "plugin";
153#else
492d5973 154static const char *plugin_target = NULL;
92b1b678 155#endif
492d5973 156
90b79792
AM
157static const char *target = NULL;
158
197245e3
FS
159enum long_option_numbers
160{
161 OPTION_PLUGIN = 201,
162 OPTION_TARGET,
163 OPTION_OUTPUT
164};
165
166static const char * output_dir = NULL;
4e407551
AM
167
168static struct option long_options[] =
169{
170 {"help", no_argument, &show_help, 1},
171 {"plugin", required_argument, NULL, OPTION_PLUGIN},
90b79792 172 {"target", required_argument, NULL, OPTION_TARGET},
4e407551 173 {"version", no_argument, &show_version, 1},
197245e3 174 {"output", required_argument, NULL, OPTION_OUTPUT},
f3016d6c 175 {"record-libdeps", required_argument, NULL, 'l'},
4e407551
AM
176 {NULL, no_argument, NULL, 0}
177};
178
252b5132
RH
179int interactive = 0;
180
181static void
2da42df6 182mri_emul (void)
252b5132
RH
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
192static void
2da42df6 193map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
252b5132
RH
194{
195 bfd *head;
3de39064 196 int match_count;
252b5132
RH
197
198 if (count == 0)
199 {
cc481421 200 for (head = arch->archive_next; head; head = head->archive_next)
252b5132
RH
201 {
202 PROGRESS (1);
203 function (head);
204 }
205 return;
206 }
3de39064 207
252b5132
RH
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
0e135a02
NC
214 for (head = arch->archive_next; head; head = head->archive_next)
215 head->archive_pass = 0;
216
252b5132
RH
217 for (; count > 0; files++, count--)
218 {
b34976b6 219 bfd_boolean found = FALSE;
252b5132 220
3de39064 221 match_count = 0;
cc481421 222 for (head = arch->archive_next; head; head = head->archive_next)
252b5132 223 {
a8da6403
NC
224 const char * filename;
225
252b5132 226 PROGRESS (1);
0e135a02
NC
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
c177f377 235 filename = bfd_get_filename (head);
a8da6403 236 if (filename == NULL)
252b5132
RH
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 }
a8da6403
NC
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
dbcf6387
AM
249 if (filename != NULL
250 && !FILENAME_CMP (normalize (*files, arch), filename))
252b5132 251 {
3de39064
ILT
252 ++match_count;
253 if (counted_name_mode
f462a9ea 254 && match_count != counted_name_counter)
3de39064
ILT
255 {
256 /* Counting, and didn't match on count; go on to the
257 next one. */
258 continue;
259 }
260
b34976b6 261 found = TRUE;
252b5132 262 function (head);
0e135a02
NC
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;
252b5132
RH
270 }
271 }
a8da6403 272
252b5132
RH
273 if (!found)
274 /* xgettext:c-format */
275 fprintf (stderr, _("no entry %s in archive\n"), *files);
276 }
277}
278\f
b34976b6 279bfd_boolean operation_alters_arch = FALSE;
252b5132
RH
280
281static void
2da42df6 282usage (int help)
252b5132
RH
283{
284 FILE *s;
285
ce3c775b 286#if BFD_SUPPORTS_PLUGINS
dbcf6387
AM
287 /* xgettext:c-format */
288 const char *command_line
1869e86f 289 = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
dbcf6387
AM
290 " [--plugin <name>] [member-name] [count] archive-file file...\n");
291
ce3c775b 292#else
dbcf6387
AM
293 /* xgettext:c-format */
294 const char *command_line
1869e86f 295 = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
dbcf6387 296 " [member-name] [count] archive-file file...\n");
ce3c775b 297#endif
faf786e6
NC
298 s = help ? stdout : stderr;
299
1154c3ef
AM
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"));
1869e86f 311 fprintf (s, _(" t[O][v] - display contents of the archive\n"));
1154c3ef
AM
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"));
9cb80f72
RM
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 }
1154c3ef
AM
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"));
1869e86f 334 fprintf (s, _(" [O] - display offsets of files in the archive\n"));
1154c3ef
AM
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"));
f3016d6c 339 fprintf (s, _(" [l <text> ] - specify the dependencies of this library\n"));
1154c3ef
AM
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"));
c60ce34a 345 fprintf (s, _(" --target=BFDNAME - specify the target object format as BFDNAME\n"));
197245e3 346 fprintf (s, _(" --output=DIRNAME - specify the output directory for extraction operations\n"));
f3016d6c 347 fprintf (s, _(" --record-libdeps=<text> - specify the dependencies of this library\n"));
ce3c775b 348#if BFD_SUPPORTS_PLUGINS
1154c3ef
AM
349 fprintf (s, _(" optional:\n"));
350 fprintf (s, _(" --plugin <p> - load the specified plugin\n"));
ce3c775b 351#endif
1154c3ef
AM
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
363static void
dbcf6387 364ranlib_usage (int help)
1154c3ef
AM
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\
d46fc8e8 374 @<file> Read options from <file>\n"));
ce3c775b 375#if BFD_SUPPORTS_PLUGINS
1154c3ef 376 fprintf (s, _("\
d46fc8e8 377 --plugin <name> Load the specified plugin\n"));
ce3c775b 378#endif
9cb80f72
RM
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"));
1154c3ef 387 fprintf (s, _("\
d46fc8e8 388 -t Update the archive's symbol map timestamp\n\
8b53311e 389 -h --help Print this help message\n\
20c0b65d 390 -v --version Print version information\n"));
252b5132 391
92f01d61 392 list_supported_targets (program_name, s);
252b5132 393
92f01d61 394 if (REPORT_BUGS_TO[0] && help)
8ad3436c 395 fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
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
403static const char *
2da42df6 404normalize (const char *file, bfd *abfd)
252b5132
RH
405{
406 const char *filename;
407
fe84ea5d 408 if (full_pathname)
b059661e 409 return file;
fe84ea5d 410
fd3a6816 411 filename = lbasename (file);
252b5132
RH
412
413 if (ar_truncate
414 && abfd != NULL
415 && strlen (filename) > abfd->xvec->ar_max_namelen)
416 {
417 char *s;
418
419 /* Space leak. */
3f5e193b 420 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
252b5132
RH
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
c8446de5 431static const char *output_filename = NULL;
252b5132
RH
432static FILE *output_file = NULL;
433static bfd *output_bfd = NULL;
434
435static void
2da42df6 436remove_output (void)
252b5132
RH
437{
438 if (output_filename != NULL)
439 {
c92c35e7
AC
440 if (output_bfd != NULL)
441 bfd_cache_close (output_bfd);
252b5132
RH
442 if (output_file != NULL)
443 fclose (output_file);
bb14f524 444 unlink_if_ordinary (output_filename);
252b5132
RH
445 }
446}
447
4e407551 448static char **
dbcf6387 449decode_options (int argc, char **argv)
4e407551
AM
450{
451 int c;
452
2f86d559 453 /* Convert old-style ar call by exploding option element and rearranging
4e407551
AM
454 options accordingly. */
455
2f86d559 456 restart:
4e407551
AM
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
f3016d6c 499 while ((c = getopt_long (argc, argv, "hdmpqrtxl:coOVsSuvabiMNfPTDU",
4e407551
AM
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':
f3016d6c
HC
547 if (libdeps != NULL)
548 fatal (_("libdeps specified more than once"));
549 libdeps = optarg;
4e407551
AM
550 break;
551 case 'c':
552 silent_create = 1;
553 break;
554 case 'o':
555 preserve_dates = 1;
556 break;
1869e86f
AB
557 case 'O':
558 display_offsets = 1;
559 break;
4e407551
AM
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;
9cb80f72
RM
602 case 'U':
603 deterministic = FALSE;
604 break;
4e407551
AM
605 case OPTION_PLUGIN:
606#if BFD_SUPPORTS_PLUGINS
4e407551
AM
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;
90b79792
AM
613 case OPTION_TARGET:
614 target = optarg;
615 break;
197245e3
FS
616 case OPTION_OUTPUT:
617 output_dir = optarg;
618 break;
4e407551
AM
619 case 0: /* A long option that just sets a flag. */
620 break;
621 default:
4e407551
AM
622 usage (0);
623 }
624 }
625
2f86d559
NC
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. */
b7d9d3ee
AM
629 if (operation == none && write_armap != 1 && !mri_mode
630 && optind > 0 && optind < argc)
2f86d559
NC
631 {
632 argv += (optind - 1);
633 argc -= (optind - 1);
634 optind = 0;
635 goto restart;
636 }
637
4e407551
AM
638 return &argv[optind];
639}
640
955d0b3b 641/* If neither -D nor -U was specified explicitly,
9cb80f72
RM
642 then use the configured default. */
643static void
644default_deterministic (void)
645{
646 if (deterministic < 0)
647 deterministic = DEFAULT_AR_DETERMINISTIC;
648}
649
1154c3ef 650static void
dbcf6387 651ranlib_main (int argc, char **argv)
1154c3ef
AM
652{
653 int arg_index, status = 0;
654 bfd_boolean touch = FALSE;
4e407551 655 int c;
1154c3ef 656
9cb80f72 657 while ((c = getopt_long (argc, argv, "DhHUvVt", long_options, NULL)) != EOF)
1154c3ef 658 {
4e407551
AM
659 switch (c)
660 {
b3364cb9
RM
661 case 'D':
662 deterministic = TRUE;
663 break;
9cb80f72
RM
664 case 'U':
665 deterministic = FALSE;
666 break;
4e407551
AM
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;
36e32b27
NC
678
679 /* PR binutils/13493: Support plugins. */
680 case OPTION_PLUGIN:
681#if BFD_SUPPORTS_PLUGINS
36e32b27
NC
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 }
1154c3ef
AM
689 }
690
4e407551 691 if (argc < 2)
1154c3ef
AM
692 ranlib_usage (0);
693
4e407551 694 if (show_help)
b3364cb9 695 ranlib_usage (1);
4e407551
AM
696
697 if (show_version)
1154c3ef 698 print_version ("ranlib");
1154c3ef 699
9cb80f72
RM
700 default_deterministic ();
701
c60ce34a 702 arg_index = optind;
1154c3ef
AM
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
2da42df6 716int main (int, char **);
65de42c0 717
252b5132 718int
2da42df6 719main (int argc, char **argv)
252b5132 720{
252b5132
RH
721 int arg_index;
722 char **files;
3de39064 723 int file_count;
252b5132 724 char *inarch_filename;
eb1e0e80 725 int i;
252b5132
RH
726
727#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
728 setlocale (LC_MESSAGES, "");
3882b010
L
729#endif
730#if defined (HAVE_SETLOCALE)
731 setlocale (LC_CTYPE, "");
252b5132
RH
732#endif
733 bindtextdomain (PACKAGE, LOCALEDIR);
734 textdomain (PACKAGE);
735
736 program_name = argv[0];
737 xmalloc_set_program_name (program_name);
86eafac0 738 bfd_set_error_program_name (program_name);
fc579192 739#if BFD_SUPPORTS_PLUGINS
3d98c460 740 bfd_plugin_set_program_name (program_name);
fc579192 741#endif
252b5132 742
869b9d07
MM
743 expandargv (&argc, &argv);
744
252b5132
RH
745 if (is_ranlib < 0)
746 {
fd3a6816
TG
747 const char *temp = lbasename (program_name);
748
252b5132 749 if (strlen (temp) >= 6
5af11cab 750 && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
252b5132
RH
751 is_ranlib = 1;
752 else
753 is_ranlib = 0;
754 }
755
252b5132
RH
756 START_PROGRESS (program_name, 0);
757
bf2dd8d7
AM
758 if (bfd_init () != BFD_INIT_MAGIC)
759 fatal (_("fatal error: libbfd ABI mismatch"));
252b5132
RH
760 set_default_bfd_target ();
761
252b5132
RH
762 xatexit (remove_output);
763
eb1e0e80
NC
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);
f462a9ea 769
252b5132 770 if (is_ranlib)
dbcf6387 771 ranlib_main (argc, argv);
252b5132
RH
772
773 if (argc < 2)
774 usage (0);
775
dbcf6387 776 argv = decode_options (argc, argv);
ce3c775b 777
4e407551 778 if (show_help)
dbcf6387 779 usage (1);
252b5132
RH
780
781 if (show_version)
782 print_version ("ar");
783
4e407551 784 arg_index = 0;
252b5132
RH
785
786 if (mri_mode)
787 {
5cd84a72 788 default_deterministic ();
252b5132
RH
789 mri_emul ();
790 }
791 else
792 {
793 bfd *arch;
794
2a925816
NC
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
84e43642
BE
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
252b5132
RH
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)
d68c385b 812 xexit (ranlib_only (argv[arg_index]));
252b5132
RH
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
9cb80f72
RM
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 ();
36e4dce6 828
252b5132 829 if (postype != pos_default)
42354845
AM
830 {
831 posname = argv[arg_index++];
832 if (posname == NULL)
833 fatal (_("missing position arg."));
834 }
252b5132 835
f462a9ea 836 if (counted_name_mode)
3de39064 837 {
3f5e193b 838 if (operation != extract && operation != del)
dbcf6387 839 fatal (_("`N' is only meaningful with the `x' and `d' options."));
42354845
AM
840 if (argv[arg_index] == NULL)
841 fatal (_("`N' missing value."));
3de39064 842 counted_name_counter = atoi (argv[arg_index++]);
f462a9ea 843 if (counted_name_counter <= 0)
3de39064
ILT
844 fatal (_("Value for `N' must be positive."));
845 }
846
252b5132 847 inarch_filename = argv[arg_index++];
7034215f
AM
848 if (inarch_filename == NULL)
849 usage (0);
252b5132 850
4e407551 851 for (file_count = 0; argv[arg_index + file_count] != NULL; file_count++)
dbcf6387 852 continue;
4e407551
AM
853
854 files = (file_count > 0) ? argv + arg_index : NULL;
252b5132 855
252b5132
RH
856 arch = open_inarch (inarch_filename,
857 files == NULL ? (char *) NULL : files[0]);
858
a8da6403
NC
859 if (operation == extract && bfd_is_thin_archive (arch))
860 fatal (_("`x' cannot be used on thin archives."));
861
f3016d6c
HC
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
c9af3845 870 must set the type back to default otherwise adding it to the
f3016d6c
HC
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
c9af3845 891 if (bfd_find_target (plugin_target, libdeps_bfd) == NULL)
f3016d6c
HC
892 fatal (_("Cannot reset libdeps record type."));
893
0833984d
HC
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. */
f3016d6c 898 new_files = xmalloc ((file_count + 2) * sizeof (char *));
0833984d
HC
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;
f3016d6c
HC
904 files = new_files;
905 files[i] = NULL;
906 }
907
252b5132
RH
908 switch (operation)
909 {
910 case print_table:
3de39064 911 map_over_members (arch, print_descr, files, file_count);
252b5132
RH
912 break;
913
914 case print_files:
3de39064 915 map_over_members (arch, print_contents, files, file_count);
252b5132
RH
916 break;
917
918 case extract:
3de39064 919 map_over_members (arch, extract_file, files, file_count);
252b5132
RH
920 break;
921
3f5e193b 922 case del:
252b5132
RH
923 if (files != NULL)
924 delete_members (arch, files);
a20a10a6
ILT
925 else
926 output_filename = NULL;
252b5132
RH
927 break;
928
929 case move:
75d5a45f
NC
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. */
252b5132
RH
941
942 case replace:
943 case quick_append:
944 if (files != NULL || write_armap > 0)
945 replace_members (arch, files, operation == quick_append);
a20a10a6
ILT
946 else
947 output_filename = NULL;
252b5132
RH
948 break;
949
950 /* Shouldn't happen! */
951 default:
952 /* xgettext:c-format */
37cc8ec1 953 fatal (_("internal error -- this option not implemented"));
252b5132
RH
954 }
955 }
956
957 END_PROGRESS (program_name);
958
959 xexit (0);
960 return 0;
961}
962
963bfd *
2da42df6 964open_inarch (const char *archive_filename, const char *file)
252b5132 965{
252b5132
RH
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
90b79792
AM
974 if (target == NULL)
975 target = plugin_target;
252b5132
RH
976
977 if (stat (archive_filename, &sbuf) != 0)
978 {
5af11cab
AM
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. */
252b5132 985
dbcf6387
AM
986 /* KLUDGE ALERT! Temporary fix until I figger why
987 stat() is wrong ... think it's buried in GO32's IDT - Jax */
252b5132
RH
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
746c5e8c
L
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)
252b5132
RH
1003 {
1004 bfd *obj;
1005
492d5973 1006 obj = bfd_openr (file, target);
252b5132
RH
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);
e9915835
NC
1021 else if (!silent_create)
1022 non_fatal (_("creating %s"), archive_filename);
c8446de5
ILT
1023
1024 /* If we die creating a new archive, don't leave it around. */
1025 output_filename = archive_filename;
252b5132
RH
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
a043396b
NC
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 }
3aade688 1063 }
a043396b 1064
cc481421 1065 last_one = &(arch->archive_next);
252b5132
RH
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;
cc481421 1073 last_one = &next_one->archive_next;
252b5132
RH
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
1081static void
2da42df6 1082print_contents (bfd *abfd)
252b5132 1083{
34debcd1
NC
1084 bfd_size_type ncopied = 0;
1085 bfd_size_type size;
3f5e193b 1086 char *cbuf = (char *) xmalloc (BUFSIZE);
252b5132 1087 struct stat buf;
34debcd1 1088
252b5132
RH
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)
cc5914eb 1094 printf ("\n<%s>\n\n", bfd_get_filename (abfd));
252b5132 1095
e59b4dfb 1096 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
252b5132
RH
1097
1098 size = buf.st_size;
1099 while (ncopied < size)
1100 {
34debcd1
NC
1101 bfd_size_type nread;
1102 bfd_size_type tocopy = size - ncopied;
252b5132 1103
252b5132
RH
1104 if (tocopy > BUFSIZE)
1105 tocopy = BUFSIZE;
1106
34debcd1 1107 nread = bfd_bread (cbuf, tocopy, abfd);
252b5132
RH
1108 if (nread != tocopy)
1109 /* xgettext:c-format */
1110 fatal (_("%s is not a valid archive"),
3860d2b4 1111 bfd_get_filename (abfd->my_archive));
84f1d826 1112
34debcd1
NC
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
84f1d826 1115 unsigned values. */
34debcd1 1116 if ((bfd_size_type) fwrite (cbuf, 1, nread, stdout) != nread)
7bd7b3ef 1117 fatal ("stdout: %s", strerror (errno));
252b5132
RH
1118 ncopied += tocopy;
1119 }
1120 free (cbuf);
1121}
1122
197245e3
FS
1123
1124static FILE * open_output_file (bfd *) ATTRIBUTE_RETURNS_NONNULL;
1125
1126static FILE *
1127open_output_file (bfd * abfd)
1128{
1129 output_filename = bfd_get_filename (abfd);
1130
e264b5b7
NC
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 }
0833984d 1142
197245e3
FS
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 }
197245e3 1156
e264b5b7
NC
1157 if (verbose)
1158 printf ("x - %s\n", output_filename);
0833984d 1159
197245e3
FS
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
252b5132
RH
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
1180void
2da42df6 1181extract_file (bfd *abfd)
252b5132 1182{
34debcd1 1183 bfd_size_type size;
252b5132 1184 struct stat buf;
f462a9ea 1185
252b5132
RH
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
e59b4dfb 1191 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
252b5132 1192
197245e3 1193 output_file = NULL;
252b5132
RH
1194 if (size == 0)
1195 {
197245e3
FS
1196 output_file = open_output_file (abfd);
1197 }
1198 else
1199 {
1200 bfd_size_type ncopied = 0;
1201 char *cbuf = (char *) xmalloc (BUFSIZE);
252b5132 1202
197245e3 1203 while (ncopied < size)
252b5132 1204 {
197245e3
FS
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;
252b5132
RH
1228 }
1229
197245e3 1230 free (cbuf);
252b5132 1231 }
197245e3
FS
1232
1233 fclose (output_file);
252b5132
RH
1234
1235 output_file = NULL;
252b5132 1236
197245e3 1237 chmod (output_filename, buf.st_mode);
252b5132
RH
1238
1239 if (preserve_dates)
b3f21e4a
JJ
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;
197245e3 1244 set_times (output_filename, &buf);
b3f21e4a 1245 }
252b5132 1246
197245e3 1247 output_filename = NULL;
252b5132
RH
1248}
1249
252b5132 1250static void
2da42df6 1251write_archive (bfd *iarch)
252b5132
RH
1252{
1253 bfd *obfd;
1254 char *old_name, *new_name;
cc481421 1255 bfd *contents_head = iarch->archive_next;
365f5fb6 1256 int ofd = -1;
014cc7f8
SP
1257 struct stat target_stat;
1258 bfd_boolean skip_stat = FALSE;
252b5132 1259
3f5e193b 1260 old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
252b5132 1261 strcpy (old_name, bfd_get_filename (iarch));
365f5fb6 1262 new_name = make_tempname (old_name, &ofd);
252b5132 1263
f9c026a8 1264 if (new_name == NULL)
9cf03b7e 1265 bfd_fatal (_("could not create temporary file whilst writing archive"));
a8da6403 1266
252b5132
RH
1267 output_filename = new_name;
1268
365f5fb6 1269 obfd = bfd_fdopenw (new_name, bfd_get_target (iarch), ofd);
252b5132
RH
1270
1271 if (obfd == NULL)
365f5fb6
SP
1272 {
1273 close (ofd);
1274 bfd_fatal (old_name);
1275 }
252b5132
RH
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
36e4dce6
CD
1292 if (deterministic)
1293 obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1294
95cc7c16
AM
1295 if (full_pathname)
1296 obfd->flags |= BFD_ARCHIVE_FULL_PATH;
1297
a8da6403 1298 if (make_thin_archive || bfd_is_thin_archive (iarch))
00f93c44 1299 bfd_set_thin_archive (obfd, TRUE);
a8da6403 1300
b34976b6 1301 if (!bfd_set_archive_head (obfd, contents_head))
252b5132
RH
1302 bfd_fatal (old_name);
1303
014cc7f8
SP
1304#if !defined (_WIN32) || defined (__CYGWIN32__)
1305 ofd = dup (ofd);
1306 if (iarch == NULL || iarch->iostream == NULL)
1307 skip_stat = TRUE;
b143e2d5 1308 else if (ofd == -1 || fstat (fileno ((FILE *) iarch->iostream), &target_stat) != 0)
014cc7f8
SP
1309 bfd_fatal (old_name);
1310#endif
1311
252b5132
RH
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
014cc7f8 1321 if (smart_rename (new_name, old_name, ofd, skip_stat ? NULL : &target_stat, 0) != 0)
252b5132 1322 xexit (1);
8e4850a9 1323 free (old_name);
3cfd3dd0 1324 free (new_name);
252b5132
RH
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
1331static bfd **
2da42df6 1332get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
252b5132
RH
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)
cc481421 1352 after_bfd = &((*after_bfd)->archive_next);
252b5132
RH
1353 }
1354 else
1355 {
cc481421 1356 for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
c177f377 1357 if (FILENAME_CMP (bfd_get_filename (*after_bfd), realposname) == 0)
252b5132
RH
1358 {
1359 if (realpos == pos_after)
cc481421 1360 after_bfd = &(*after_bfd)->archive_next;
252b5132
RH
1361 break;
1362 }
1363 }
1364 return after_bfd;
1365}
1366
1367static void
2da42df6 1368delete_members (bfd *arch, char **files_to_delete)
252b5132
RH
1369{
1370 bfd **current_ptr_ptr;
b34976b6
AM
1371 bfd_boolean found;
1372 bfd_boolean something_changed = FALSE;
3de39064
ILT
1373 int match_count;
1374
252b5132
RH
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 {
b34976b6 1385 arch->has_armap = FALSE;
252b5132
RH
1386 write_armap = -1;
1387 continue;
1388 }
1389
b34976b6 1390 found = FALSE;
3de39064 1391 match_count = 0;
cc481421 1392 current_ptr_ptr = &(arch->archive_next);
252b5132
RH
1393 while (*current_ptr_ptr)
1394 {
4510857d 1395 if (FILENAME_CMP (normalize (*files_to_delete, arch),
c177f377 1396 bfd_get_filename (*current_ptr_ptr)) == 0)
252b5132 1397 {
3de39064
ILT
1398 ++match_count;
1399 if (counted_name_mode
f462a9ea 1400 && match_count != counted_name_counter)
3de39064
ILT
1401 {
1402 /* Counting, and didn't match on count; go on to the
1403 next one. */
1404 }
1405 else
1406 {
b34976b6
AM
1407 found = TRUE;
1408 something_changed = TRUE;
3de39064
ILT
1409 if (verbose)
1410 printf ("d - %s\n",
1411 *files_to_delete);
cc481421 1412 *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
3de39064
ILT
1413 goto next_file;
1414 }
252b5132 1415 }
3de39064 1416
cc481421 1417 current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
252b5132
RH
1418 }
1419
b34976b6 1420 if (verbose && !found)
252b5132
RH
1421 {
1422 /* xgettext:c-format */
1423 printf (_("No member named `%s'\n"), *files_to_delete);
1424 }
1425 next_file:
1426 ;
1427 }
1428
b34976b6 1429 if (something_changed)
a20a10a6
ILT
1430 write_archive (arch);
1431 else
1432 output_filename = NULL;
252b5132
RH
1433}
1434
1435
1436/* Reposition existing members within an archive */
1437
1438static void
2da42df6 1439move_members (bfd *arch, char **files_to_move)
252b5132 1440{
4510857d
AM
1441 bfd **after_bfd; /* New entries go after this one */
1442 bfd **current_ptr_ptr; /* cdr pointer into contents */
252b5132
RH
1443
1444 for (; *files_to_move; ++files_to_move)
1445 {
cc481421 1446 current_ptr_ptr = &(arch->archive_next);
252b5132
RH
1447 while (*current_ptr_ptr)
1448 {
1449 bfd *current_ptr = *current_ptr_ptr;
4510857d 1450 if (FILENAME_CMP (normalize (*files_to_move, arch),
c177f377 1451 bfd_get_filename (current_ptr)) == 0)
252b5132
RH
1452 {
1453 /* Move this file to the end of the list - first cut from
1454 where it is. */
91d6fa6a 1455 bfd *link_bfd;
cc481421 1456 *current_ptr_ptr = current_ptr->archive_next;
252b5132
RH
1457
1458 /* Now glue to end */
cc481421 1459 after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
91d6fa6a 1460 link_bfd = *after_bfd;
252b5132 1461 *after_bfd = current_ptr;
91d6fa6a 1462 current_ptr->archive_next = link_bfd;
252b5132
RH
1463
1464 if (verbose)
1465 printf ("m - %s\n", *files_to_move);
1466
1467 goto next_file;
1468 }
1469
cc481421 1470 current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
252b5132
RH
1471 }
1472 /* xgettext:c-format */
c177f377
AM
1473 fatal (_("no entry %s in archive %s!"), *files_to_move,
1474 bfd_get_filename (arch));
37cc8ec1 1475
4510857d 1476 next_file:;
252b5132
RH
1477 }
1478
1479 write_archive (arch);
1480}
1481
1482/* Ought to default to replacing in place, but this is existing practice! */
1483
1484static void
2da42df6 1485replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
252b5132 1486{
b34976b6 1487 bfd_boolean changed = FALSE;
360589e8 1488 bfd **after_bfd; /* New entries go after this one. */
252b5132
RH
1489 bfd *current;
1490 bfd **current_ptr;
252b5132
RH
1491
1492 while (files_to_move && *files_to_move)
1493 {
1494 if (! quick)
1495 {
cc481421 1496 current_ptr = &arch->archive_next;
252b5132
RH
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. */
5af11cab 1503 if (FILENAME_CMP (normalize (*files_to_move, arch),
c177f377 1504 normalize (bfd_get_filename (current), arch)) == 0
252b5132
RH
1505 && current->arelt_data != NULL)
1506 {
f3016d6c 1507 bfd_boolean replaced;
252b5132
RH
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 */
e58a75dc 1520 fatal (_("internal stat error on %s"),
c177f377 1521 bfd_get_filename (current));
252b5132
RH
1522
1523 if (fsbuf.st_mtime <= asbuf.st_mtime)
1524 goto next_file;
1525 }
1526
cc481421 1527 after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
c177f377 1528 bfd_get_filename (current));
f3016d6c
HC
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)
252b5132 1542 {
eb1e0e80 1543 /* Snip out this entry from the chain. */
cc481421 1544 *current_ptr = (*current_ptr)->archive_next;
b34976b6 1545 changed = TRUE;
252b5132 1546 }
252b5132
RH
1547
1548 goto next_file;
1549 }
cc481421 1550 current_ptr = &(current->archive_next);
252b5132
RH
1551 }
1552 }
1553
1554 /* Add to the end of the archive. */
cc481421 1555 after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
f24ddbdd 1556
f3016d6c
HC
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 }
252b5132
RH
1568
1569 next_file:;
1570
1571 files_to_move++;
1572 }
1573
1574 if (changed)
1575 write_archive (arch);
a20a10a6
ILT
1576 else
1577 output_filename = NULL;
252b5132
RH
1578}
1579
d68c385b 1580static int
2da42df6 1581ranlib_only (const char *archname)
252b5132
RH
1582{
1583 bfd *arch;
1584
f24ddbdd 1585 if (get_file_size (archname) < 1)
d68c385b 1586 return 1;
252b5132
RH
1587 write_armap = 1;
1588 arch = open_inarch (archname, (char *) NULL);
1589 if (arch == NULL)
1590 xexit (1);
1591 write_archive (arch);
d68c385b 1592 return 0;
252b5132
RH
1593}
1594
1595/* Update the timestamp of the symbol map of an archive. */
1596
d68c385b 1597static int
2da42df6 1598ranlib_touch (const char *archname)
252b5132
RH
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
f24ddbdd 1608 if (get_file_size (archname) < 1)
d68c385b 1609 return 1;
d84feeac 1610 f = open (archname, O_RDWR | O_BINARY, 0);
252b5132
RH
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
b3364cb9
RM
1635 if (deterministic)
1636 arch->flags |= BFD_DETERMINISTIC_OUTPUT;
1637
252b5132
RH
1638 bfd_update_armap_timestamp (arch);
1639
1640 if (! bfd_close (arch))
1641 bfd_fatal (archname);
1642#endif
d68c385b 1643 return 0;
252b5132
RH
1644}
1645
1646/* Things which are interesting to map over all or some of the files: */
1647
1648static void
2da42df6 1649print_descr (bfd *abfd)
252b5132 1650{
1869e86f 1651 print_arelt_descr (stdout, abfd, verbose, display_offsets);
252b5132 1652}