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