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