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