Merge branch 'vendor/OPENSSL'
[dragonfly.git] / contrib / binutils-2.20 / 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       fprintf (s, _("\
284   --plugin <name>              Load the specified plugin\n"));
285 #endif
286       fprintf (s, _("\
287   -t                           Update the archive's symbol map timestamp\n\
288   -h --help                    Print this help message\n\
289   -v --version                 Print version information\n"));
290     }
291
292   list_supported_targets (program_name, s);
293
294   if (REPORT_BUGS_TO[0] && help)
295     fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
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
303 static const char *
304 normalize (const char *file, bfd *abfd)
305 {
306   const char *filename;
307
308   if (full_pathname)
309     return file;
310
311   filename = strrchr (file, '/');
312 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
313   {
314     /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
315     char *bslash = strrchr (file, '\\');
316
317     if (filename == NULL || (bslash != NULL && bslash > filename))
318       filename = bslash;
319     if (filename == NULL && file[0] != '\0' && file[1] == ':')
320       filename = file + 1;
321   }
322 #endif
323   if (filename != (char *) NULL)
324     filename++;
325   else
326     filename = file;
327
328   if (ar_truncate
329       && abfd != NULL
330       && strlen (filename) > abfd->xvec->ar_max_namelen)
331     {
332       char *s;
333
334       /* Space leak.  */
335       s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
336       memcpy (s, filename, abfd->xvec->ar_max_namelen);
337       s[abfd->xvec->ar_max_namelen] = '\0';
338       filename = s;
339     }
340
341   return filename;
342 }
343
344 /* Remove any output file.  This is only called via xatexit.  */
345
346 static const char *output_filename = NULL;
347 static FILE *output_file = NULL;
348 static bfd *output_bfd = NULL;
349
350 static void
351 remove_output (void)
352 {
353   if (output_filename != NULL)
354     {
355       if (output_bfd != NULL)
356         bfd_cache_close (output_bfd);
357       if (output_file != NULL)
358         fclose (output_file);
359       unlink_if_ordinary (output_filename);
360     }
361 }
362
363 /* The option parsing should be in its own function.
364    It will be when I have getopt working.  */
365
366 int main (int, char **);
367
368 int
369 main (int argc, char **argv)
370 {
371   char *arg_ptr;
372   char c;
373   enum
374     {
375       none = 0, del, replace, print_table,
376       print_files, extract, move, quick_append
377     } operation = none;
378   int arg_index;
379   char **files;
380   int file_count;
381   char *inarch_filename;
382   int show_version;
383   int i;
384   int do_posix = 0;
385
386 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
387   setlocale (LC_MESSAGES, "");
388 #endif
389 #if defined (HAVE_SETLOCALE)
390   setlocale (LC_CTYPE, "");
391 #endif
392   bindtextdomain (PACKAGE, LOCALEDIR);
393   textdomain (PACKAGE);
394
395   program_name = argv[0];
396   xmalloc_set_program_name (program_name);
397 #if BFD_SUPPORTS_PLUGINS
398   bfd_plugin_set_program_name (program_name);
399 #endif
400
401   expandargv (&argc, &argv);
402
403   if (is_ranlib < 0)
404     {
405       char *temp;
406
407       temp = strrchr (program_name, '/');
408 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
409       {
410         /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
411         char *bslash = strrchr (program_name, '\\');
412
413         if (temp == NULL || (bslash != NULL && bslash > temp))
414           temp = bslash;
415         if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
416           temp = program_name + 1;
417       }
418 #endif
419       if (temp == NULL)
420         temp = program_name;
421       else
422         ++temp;
423       if (strlen (temp) >= 6
424           && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
425         is_ranlib = 1;
426       else
427         is_ranlib = 0;
428     }
429
430   if (argc > 1 && argv[1][0] == '-')
431     {
432       if (strcmp (argv[1], "--help") == 0)
433         usage (1);
434       else if (strcmp (argv[1], "--version") == 0)
435         {
436           if (is_ranlib)
437             print_version ("ranlib");
438           else
439             print_version ("ar");
440         }
441     }
442
443   START_PROGRESS (program_name, 0);
444
445   bfd_init ();
446   set_default_bfd_target ();
447
448   show_version = 0;
449
450   xatexit (remove_output);
451
452   for (i = 1; i < argc; i++)
453     if (! ar_emul_parse_arg (argv[i]))
454       break;
455   argv += (i - 1);
456   argc -= (i - 1);
457
458   if (is_ranlib)
459     {
460       int status = 0;
461       bfd_boolean touch = FALSE;
462
463       if (argc < 2
464           || strcmp (argv[1], "--help") == 0
465           || strcmp (argv[1], "-h") == 0
466           || strcmp (argv[1], "-H") == 0)
467         usage (0);
468       if (strcmp (argv[1], "-V") == 0
469           || strcmp (argv[1], "-v") == 0
470           || CONST_STRNEQ (argv[1], "--v"))
471         print_version ("ranlib");
472       arg_index = 1;
473       if (strcmp (argv[1], "-t") == 0)
474         {
475           ++arg_index;
476           touch = TRUE;
477         }
478       while (arg_index < argc)
479         {
480           if (! touch)
481             status |= ranlib_only (argv[arg_index]);
482           else
483             status |= ranlib_touch (argv[arg_index]);
484           ++arg_index;
485         }
486       xexit (status);
487     }
488
489   if (argc == 2 && strcmp (argv[1], "-M") == 0)
490     {
491       mri_emul ();
492       xexit (0);
493     }
494
495   if (argc < 2)
496     usage (0);
497
498   arg_index = 1;
499   arg_ptr = argv[arg_index];
500
501   if (strcmp (arg_ptr, "--plugin") == 0)
502     {
503 #if BFD_SUPPORTS_PLUGINS
504       if (argc < 4)
505         usage (1);
506
507       bfd_plugin_set_plugin (argv[2]);
508
509       arg_index += 2;
510       arg_ptr = argv[arg_index];
511 #else
512       fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
513       xexit (1);
514 #endif
515     }
516
517   if (*arg_ptr == '-')
518     {
519       /* When the first option starts with '-' we support POSIX-compatible
520          option parsing.  */
521       do_posix = 1;
522       ++arg_ptr;                        /* compatibility */
523     }
524
525   do
526     {
527       while ((c = *arg_ptr++) != '\0')
528         {
529           switch (c)
530             {
531             case 'd':
532             case 'm':
533             case 'p':
534             case 'q':
535             case 'r':
536             case 't':
537             case 'x':
538               if (operation != none)
539                 fatal (_("two different operation options specified"));
540               switch (c)
541                 {
542                 case 'd':
543                   operation = del;
544                   operation_alters_arch = TRUE;
545                   break;
546                 case 'm':
547                   operation = move;
548                   operation_alters_arch = TRUE;
549                   break;
550                 case 'p':
551                   operation = print_files;
552                   break;
553                 case 'q':
554                   operation = quick_append;
555                   operation_alters_arch = TRUE;
556                   break;
557                 case 'r':
558                   operation = replace;
559                   operation_alters_arch = TRUE;
560                   break;
561                 case 't':
562                   operation = print_table;
563                   break;
564                 case 'x':
565                   operation = extract;
566                   break;
567                 }
568             case 'l':
569               break;
570             case 'c':
571               silent_create = 1;
572               break;
573             case 'o':
574               preserve_dates = 1;
575               break;
576             case 'V':
577               show_version = TRUE;
578               break;
579             case 's':
580               write_armap = 1;
581               break;
582             case 'S':
583               write_armap = -1;
584               break;
585             case 'u':
586               newer_only = 1;
587               break;
588             case 'v':
589               verbose = 1;
590               break;
591             case 'a':
592               postype = pos_after;
593               break;
594             case 'b':
595               postype = pos_before;
596               break;
597             case 'i':
598               postype = pos_before;
599               break;
600             case 'M':
601               mri_mode = 1;
602               break;
603             case 'N':
604               counted_name_mode = TRUE;
605               break;
606             case 'f':
607               ar_truncate = TRUE;
608               break;
609             case 'P':
610               full_pathname = TRUE;
611               break;
612             case 'T':
613               make_thin_archive = TRUE;
614               break;
615             case 'D':
616               deterministic = TRUE;
617               break;
618             default:
619               /* xgettext:c-format */
620               non_fatal (_("illegal option -- %c"), c);
621               usage (0);
622             }
623         }
624
625       /* With POSIX-compatible option parsing continue with the next
626          argument if it starts with '-'.  */
627       if (do_posix && arg_index + 1 < argc && argv[arg_index + 1][0] == '-')
628         arg_ptr = argv[++arg_index] + 1;
629       else
630         do_posix = 0;
631     }
632   while (do_posix);
633
634   if (show_version)
635     print_version ("ar");
636
637   ++arg_index;
638   if (arg_index >= argc)
639     usage (0);
640
641   if (mri_mode)
642     {
643       mri_emul ();
644     }
645   else
646     {
647       bfd *arch;
648
649       /* We don't use do_quick_append any more.  Too many systems
650          expect ar to always rebuild the symbol table even when q is
651          used.  */
652
653       /* We can't write an armap when using ar q, so just do ar r
654          instead.  */
655       if (operation == quick_append && write_armap)
656         operation = replace;
657
658       if ((operation == none || operation == print_table)
659           && write_armap == 1)
660         xexit (ranlib_only (argv[arg_index]));
661
662       if (operation == none)
663         fatal (_("no operation specified"));
664
665       if (newer_only && operation != replace)
666         fatal (_("`u' is only meaningful with the `r' option."));
667
668       if (newer_only && deterministic)
669         fatal (_("`u' is not meaningful with the `D' option."));
670
671       if (postype != pos_default)
672         posname = argv[arg_index++];
673
674       if (counted_name_mode)
675         {
676           if (operation != extract && operation != del)
677              fatal (_("`N' is only meaningful with the `x' and `d' options."));
678           counted_name_counter = atoi (argv[arg_index++]);
679           if (counted_name_counter <= 0)
680             fatal (_("Value for `N' must be positive."));
681         }
682
683       inarch_filename = argv[arg_index++];
684
685       files = arg_index < argc ? argv + arg_index : NULL;
686       file_count = argc - arg_index;
687
688       arch = open_inarch (inarch_filename,
689                           files == NULL ? (char *) NULL : files[0]);
690
691       if (operation == extract && bfd_is_thin_archive (arch))
692         fatal (_("`x' cannot be used on thin archives."));
693
694       switch (operation)
695         {
696         case print_table:
697           map_over_members (arch, print_descr, files, file_count);
698           break;
699
700         case print_files:
701           map_over_members (arch, print_contents, files, file_count);
702           break;
703
704         case extract:
705           map_over_members (arch, extract_file, files, file_count);
706           break;
707
708         case del:
709           if (files != NULL)
710             delete_members (arch, files);
711           else
712             output_filename = NULL;
713           break;
714
715         case move:
716           if (files != NULL)
717             move_members (arch, files);
718           else
719             output_filename = NULL;
720           break;
721
722         case replace:
723         case quick_append:
724           if (files != NULL || write_armap > 0)
725             replace_members (arch, files, operation == quick_append);
726           else
727             output_filename = NULL;
728           break;
729
730           /* Shouldn't happen! */
731         default:
732           /* xgettext:c-format */
733           fatal (_("internal error -- this option not implemented"));
734         }
735     }
736
737   END_PROGRESS (program_name);
738
739   xexit (0);
740   return 0;
741 }
742
743 bfd *
744 open_inarch (const char *archive_filename, const char *file)
745 {
746   const char *target;
747   bfd **last_one;
748   bfd *next_one;
749   struct stat sbuf;
750   bfd *arch;
751   char **matching;
752
753   bfd_set_error (bfd_error_no_error);
754
755   target = NULL;
756
757   if (stat (archive_filename, &sbuf) != 0)
758     {
759 #if !defined(__GO32__) || defined(__DJGPP__)
760
761       /* FIXME: I don't understand why this fragment was ifndef'ed
762          away for __GO32__; perhaps it was in the days of DJGPP v1.x.
763          stat() works just fine in v2.x, so I think this should be
764          removed.  For now, I enable it for DJGPP v2. -- EZ.  */
765
766 /* KLUDGE ALERT! Temporary fix until I figger why
767    stat() is wrong ... think it's buried in GO32's IDT - Jax */
768       if (errno != ENOENT)
769         bfd_fatal (archive_filename);
770 #endif
771
772       if (!operation_alters_arch)
773         {
774           fprintf (stderr, "%s: ", program_name);
775           perror (archive_filename);
776           maybequit ();
777           return NULL;
778         }
779
780       /* Try to figure out the target to use for the archive from the
781          first object on the list.  */
782       if (file != NULL)
783         {
784           bfd *obj;
785
786           obj = bfd_openr (file, NULL);
787           if (obj != NULL)
788             {
789               if (bfd_check_format (obj, bfd_object))
790                 target = bfd_get_target (obj);
791               (void) bfd_close (obj);
792             }
793         }
794
795       /* Create an empty archive.  */
796       arch = bfd_openw (archive_filename, target);
797       if (arch == NULL
798           || ! bfd_set_format (arch, bfd_archive)
799           || ! bfd_close (arch))
800         bfd_fatal (archive_filename);
801       else if (!silent_create)
802         non_fatal (_("creating %s"), archive_filename);
803
804       /* If we die creating a new archive, don't leave it around.  */
805       output_filename = archive_filename;
806     }
807
808   arch = bfd_openr (archive_filename, target);
809   if (arch == NULL)
810     {
811     bloser:
812       bfd_fatal (archive_filename);
813     }
814
815   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
816     {
817       bfd_nonfatal (archive_filename);
818       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
819         {
820           list_matching_formats (matching);
821           free (matching);
822         }
823       xexit (1);
824     }
825
826   last_one = &(arch->archive_next);
827   /* Read all the contents right away, regardless.  */
828   for (next_one = bfd_openr_next_archived_file (arch, NULL);
829        next_one;
830        next_one = bfd_openr_next_archived_file (arch, next_one))
831     {
832       PROGRESS (1);
833       *last_one = next_one;
834       last_one = &next_one->archive_next;
835     }
836   *last_one = (bfd *) NULL;
837   if (bfd_get_error () != bfd_error_no_more_archived_files)
838     goto bloser;
839   return arch;
840 }
841
842 static void
843 print_contents (bfd *abfd)
844 {
845   size_t ncopied = 0;
846   char *cbuf = (char *) xmalloc (BUFSIZE);
847   struct stat buf;
848   size_t size;
849   if (bfd_stat_arch_elt (abfd, &buf) != 0)
850     /* xgettext:c-format */
851     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
852
853   if (verbose)
854     /* xgettext:c-format */
855     printf (_("\n<%s>\n\n"), bfd_get_filename (abfd));
856
857   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
858
859   size = buf.st_size;
860   while (ncopied < size)
861     {
862
863       size_t nread;
864       size_t tocopy = size - ncopied;
865       if (tocopy > BUFSIZE)
866         tocopy = BUFSIZE;
867
868       nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
869       if (nread != tocopy)
870         /* xgettext:c-format */
871         fatal (_("%s is not a valid archive"),
872                bfd_get_filename (bfd_my_archive (abfd)));
873
874       /* fwrite in mingw32 may return int instead of size_t. Cast the
875          return value to size_t to avoid comparison between signed and
876          unsigned values.  */
877       if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread)
878         fatal ("stdout: %s", strerror (errno));
879       ncopied += tocopy;
880     }
881   free (cbuf);
882 }
883
884 /* Extract a member of the archive into its own file.
885
886    We defer opening the new file until after we have read a BUFSIZ chunk of the
887    old one, since we know we have just read the archive header for the old
888    one.  Since most members are shorter than BUFSIZ, this means we will read
889    the old header, read the old data, write a new inode for the new file, and
890    write the new data, and be done. This 'optimization' is what comes from
891    sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
892    Gilmore  */
893
894 void
895 extract_file (bfd *abfd)
896 {
897   FILE *ostream;
898   char *cbuf = (char *) xmalloc (BUFSIZE);
899   size_t nread, tocopy;
900   size_t ncopied = 0;
901   size_t size;
902   struct stat buf;
903
904   if (bfd_stat_arch_elt (abfd, &buf) != 0)
905     /* xgettext:c-format */
906     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
907   size = buf.st_size;
908
909   if (verbose)
910     printf ("x - %s\n", bfd_get_filename (abfd));
911
912   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
913
914   ostream = NULL;
915   if (size == 0)
916     {
917       /* Seems like an abstraction violation, eh?  Well it's OK! */
918       output_filename = bfd_get_filename (abfd);
919
920       ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
921       if (ostream == NULL)
922         {
923           perror (bfd_get_filename (abfd));
924           xexit (1);
925         }
926
927       output_file = ostream;
928     }
929   else
930     while (ncopied < size)
931       {
932         tocopy = size - ncopied;
933         if (tocopy > BUFSIZE)
934           tocopy = BUFSIZE;
935
936         nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
937         if (nread != tocopy)
938           /* xgettext:c-format */
939           fatal (_("%s is not a valid archive"),
940                  bfd_get_filename (bfd_my_archive (abfd)));
941
942         /* See comment above; this saves disk arm motion */
943         if (ostream == NULL)
944           {
945             /* Seems like an abstraction violation, eh?  Well it's OK! */
946             output_filename = bfd_get_filename (abfd);
947
948             ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
949             if (ostream == NULL)
950               {
951                 perror (bfd_get_filename (abfd));
952                 xexit (1);
953               }
954
955             output_file = ostream;
956           }
957
958         /* fwrite in mingw32 may return int instead of size_t. Cast
959            the return value to size_t to avoid comparison between
960            signed and unsigned values.  */
961         if ((size_t) fwrite (cbuf, 1, nread, ostream) != nread)
962           fatal ("%s: %s", output_filename, strerror (errno));
963         ncopied += tocopy;
964       }
965
966   if (ostream != NULL)
967     fclose (ostream);
968
969   output_file = NULL;
970   output_filename = NULL;
971
972   chmod (bfd_get_filename (abfd), buf.st_mode);
973
974   if (preserve_dates)
975     {
976       /* Set access time to modification time.  Only st_mtime is
977          initialized by bfd_stat_arch_elt.  */
978       buf.st_atime = buf.st_mtime;
979       set_times (bfd_get_filename (abfd), &buf);
980     }
981
982   free (cbuf);
983 }
984
985 static void
986 write_archive (bfd *iarch)
987 {
988   bfd *obfd;
989   char *old_name, *new_name;
990   bfd *contents_head = iarch->archive_next;
991
992   old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
993   strcpy (old_name, bfd_get_filename (iarch));
994   new_name = make_tempname (old_name);
995
996   if (new_name == NULL)
997     bfd_fatal ("could not create temporary file whilst writing archive");
998
999   output_filename = new_name;
1000
1001   obfd = bfd_openw (new_name, bfd_get_target (iarch));
1002
1003   if (obfd == NULL)
1004     bfd_fatal (old_name);
1005
1006   output_bfd = obfd;
1007
1008   bfd_set_format (obfd, bfd_archive);
1009
1010   /* Request writing the archive symbol table unless we've
1011      been explicitly requested not to.  */
1012   obfd->has_armap = write_armap >= 0;
1013
1014   if (ar_truncate)
1015     {
1016       /* This should really use bfd_set_file_flags, but that rejects
1017          archives.  */
1018       obfd->flags |= BFD_TRADITIONAL_FORMAT;
1019     }
1020
1021   if (deterministic)
1022     obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1023
1024   if (make_thin_archive || bfd_is_thin_archive (iarch))
1025     bfd_is_thin_archive (obfd) = 1;
1026
1027   if (!bfd_set_archive_head (obfd, contents_head))
1028     bfd_fatal (old_name);
1029
1030   if (!bfd_close (obfd))
1031     bfd_fatal (old_name);
1032
1033   output_bfd = NULL;
1034   output_filename = NULL;
1035
1036   /* We don't care if this fails; we might be creating the archive.  */
1037   bfd_close (iarch);
1038
1039   if (smart_rename (new_name, old_name, 0) != 0)
1040     xexit (1);
1041 }
1042
1043 /* Return a pointer to the pointer to the entry which should be rplacd'd
1044    into when altering.  DEFAULT_POS should be how to interpret pos_default,
1045    and should be a pos value.  */
1046
1047 static bfd **
1048 get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1049 {
1050   bfd **after_bfd = contents;
1051   enum pos realpos;
1052   const char *realposname;
1053
1054   if (postype == pos_default)
1055     {
1056       realpos = default_pos;
1057       realposname = default_posname;
1058     }
1059   else
1060     {
1061       realpos = postype;
1062       realposname = posname;
1063     }
1064
1065   if (realpos == pos_end)
1066     {
1067       while (*after_bfd)
1068         after_bfd = &((*after_bfd)->archive_next);
1069     }
1070   else
1071     {
1072       for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
1073         if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1074           {
1075             if (realpos == pos_after)
1076               after_bfd = &(*after_bfd)->archive_next;
1077             break;
1078           }
1079     }
1080   return after_bfd;
1081 }
1082
1083 static void
1084 delete_members (bfd *arch, char **files_to_delete)
1085 {
1086   bfd **current_ptr_ptr;
1087   bfd_boolean found;
1088   bfd_boolean something_changed = FALSE;
1089   int match_count;
1090
1091   for (; *files_to_delete != NULL; ++files_to_delete)
1092     {
1093       /* In a.out systems, the armap is optional.  It's also called
1094          __.SYMDEF.  So if the user asked to delete it, we should remember
1095          that fact. This isn't quite right for COFF systems (where
1096          __.SYMDEF might be regular member), but it's very unlikely
1097          to be a problem.  FIXME */
1098
1099       if (!strcmp (*files_to_delete, "__.SYMDEF"))
1100         {
1101           arch->has_armap = FALSE;
1102           write_armap = -1;
1103           continue;
1104         }
1105
1106       found = FALSE;
1107       match_count = 0;
1108       current_ptr_ptr = &(arch->archive_next);
1109       while (*current_ptr_ptr)
1110         {
1111           if (FILENAME_CMP (normalize (*files_to_delete, arch),
1112                             (*current_ptr_ptr)->filename) == 0)
1113             {
1114               ++match_count;
1115               if (counted_name_mode
1116                   && match_count != counted_name_counter)
1117                 {
1118                   /* Counting, and didn't match on count; go on to the
1119                      next one.  */
1120                 }
1121               else
1122                 {
1123                   found = TRUE;
1124                   something_changed = TRUE;
1125                   if (verbose)
1126                     printf ("d - %s\n",
1127                             *files_to_delete);
1128                   *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
1129                   goto next_file;
1130                 }
1131             }
1132
1133           current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1134         }
1135
1136       if (verbose && !found)
1137         {
1138           /* xgettext:c-format */
1139           printf (_("No member named `%s'\n"), *files_to_delete);
1140         }
1141     next_file:
1142       ;
1143     }
1144
1145   if (something_changed)
1146     write_archive (arch);
1147   else
1148     output_filename = NULL;
1149 }
1150
1151
1152 /* Reposition existing members within an archive */
1153
1154 static void
1155 move_members (bfd *arch, char **files_to_move)
1156 {
1157   bfd **after_bfd;              /* New entries go after this one */
1158   bfd **current_ptr_ptr;        /* cdr pointer into contents */
1159
1160   for (; *files_to_move; ++files_to_move)
1161     {
1162       current_ptr_ptr = &(arch->archive_next);
1163       while (*current_ptr_ptr)
1164         {
1165           bfd *current_ptr = *current_ptr_ptr;
1166           if (FILENAME_CMP (normalize (*files_to_move, arch),
1167                             current_ptr->filename) == 0)
1168             {
1169               /* Move this file to the end of the list - first cut from
1170                  where it is.  */
1171               bfd *link;
1172               *current_ptr_ptr = current_ptr->archive_next;
1173
1174               /* Now glue to end */
1175               after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1176               link = *after_bfd;
1177               *after_bfd = current_ptr;
1178               current_ptr->archive_next = link;
1179
1180               if (verbose)
1181                 printf ("m - %s\n", *files_to_move);
1182
1183               goto next_file;
1184             }
1185
1186           current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1187         }
1188       /* xgettext:c-format */
1189       fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1190
1191     next_file:;
1192     }
1193
1194   write_archive (arch);
1195 }
1196
1197 /* Ought to default to replacing in place, but this is existing practice!  */
1198
1199 static void
1200 replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
1201 {
1202   bfd_boolean changed = FALSE;
1203   bfd **after_bfd;              /* New entries go after this one.  */
1204   bfd *current;
1205   bfd **current_ptr;
1206
1207   while (files_to_move && *files_to_move)
1208     {
1209       if (! quick)
1210         {
1211           current_ptr = &arch->archive_next;
1212           while (*current_ptr)
1213             {
1214               current = *current_ptr;
1215
1216               /* For compatibility with existing ar programs, we
1217                  permit the same file to be added multiple times.  */
1218               if (FILENAME_CMP (normalize (*files_to_move, arch),
1219                                 normalize (current->filename, arch)) == 0
1220                   && current->arelt_data != NULL)
1221                 {
1222                   if (newer_only)
1223                     {
1224                       struct stat fsbuf, asbuf;
1225
1226                       if (stat (*files_to_move, &fsbuf) != 0)
1227                         {
1228                           if (errno != ENOENT)
1229                             bfd_fatal (*files_to_move);
1230                           goto next_file;
1231                         }
1232                       if (bfd_stat_arch_elt (current, &asbuf) != 0)
1233                         /* xgettext:c-format */
1234                         fatal (_("internal stat error on %s"),
1235                                current->filename);
1236
1237                       if (fsbuf.st_mtime <= asbuf.st_mtime)
1238                         goto next_file;
1239                     }
1240
1241                   after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
1242                                            current->filename);
1243                   if (ar_emul_replace (after_bfd, *files_to_move,
1244                                        verbose))
1245                     {
1246                       /* Snip out this entry from the chain.  */
1247                       *current_ptr = (*current_ptr)->archive_next;
1248                       changed = TRUE;
1249                     }
1250
1251                   goto next_file;
1252                 }
1253               current_ptr = &(current->archive_next);
1254             }
1255         }
1256
1257       /* Add to the end of the archive.  */
1258       after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1259
1260       if (ar_emul_append (after_bfd, *files_to_move, verbose,
1261                           make_thin_archive))
1262         changed = TRUE;
1263
1264     next_file:;
1265
1266       files_to_move++;
1267     }
1268
1269   if (changed)
1270     write_archive (arch);
1271   else
1272     output_filename = NULL;
1273 }
1274
1275 static int
1276 ranlib_only (const char *archname)
1277 {
1278   bfd *arch;
1279
1280   if (get_file_size (archname) < 1)
1281     return 1;
1282   write_armap = 1;
1283   arch = open_inarch (archname, (char *) NULL);
1284   if (arch == NULL)
1285     xexit (1);
1286   write_archive (arch);
1287   return 0;
1288 }
1289
1290 /* Update the timestamp of the symbol map of an archive.  */
1291
1292 static int
1293 ranlib_touch (const char *archname)
1294 {
1295 #ifdef __GO32__
1296   /* I don't think updating works on go32.  */
1297   ranlib_only (archname);
1298 #else
1299   int f;
1300   bfd *arch;
1301   char **matching;
1302
1303   if (get_file_size (archname) < 1)
1304     return 1;
1305   f = open (archname, O_RDWR | O_BINARY, 0);
1306   if (f < 0)
1307     {
1308       bfd_set_error (bfd_error_system_call);
1309       bfd_fatal (archname);
1310     }
1311
1312   arch = bfd_fdopenr (archname, (const char *) NULL, f);
1313   if (arch == NULL)
1314     bfd_fatal (archname);
1315   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1316     {
1317       bfd_nonfatal (archname);
1318       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1319         {
1320           list_matching_formats (matching);
1321           free (matching);
1322         }
1323       xexit (1);
1324     }
1325
1326   if (! bfd_has_map (arch))
1327     /* xgettext:c-format */
1328     fatal (_("%s: no archive map to update"), archname);
1329
1330   bfd_update_armap_timestamp (arch);
1331
1332   if (! bfd_close (arch))
1333     bfd_fatal (archname);
1334 #endif
1335   return 0;
1336 }
1337
1338 /* Things which are interesting to map over all or some of the files: */
1339
1340 static void
1341 print_descr (bfd *abfd)
1342 {
1343   print_arelt_descr (stdout, abfd, verbose);
1344 }