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