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