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