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