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