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