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