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