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