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