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