This commit was generated by cvs2svn to track changes on a CVS vendor
[external/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 file;
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           else
651             output_filename = NULL;
652           break;
653
654         case move:
655           if (files != NULL)
656             move_members (arch, files);
657           else
658             output_filename = NULL;
659           break;
660
661         case replace:
662         case quick_append:
663           if (files != NULL || write_armap > 0)
664             replace_members (arch, files, operation == quick_append);
665           else
666             output_filename = NULL;
667           break;
668
669           /* Shouldn't happen! */
670         default:
671           /* xgettext:c-format */
672           fprintf (stderr, _("%s: internal error -- this option not implemented\n"),
673                    program_name);
674           xexit (1);
675         }
676     }
677
678   END_PROGRESS (program_name);
679
680   xexit (0);
681   return 0;
682 }
683
684 bfd *
685 open_inarch (archive_filename, file)
686      const char *archive_filename;
687      const char *file;
688 {
689   const char *target;
690   bfd **last_one;
691   bfd *next_one;
692   struct stat sbuf;
693   bfd *arch;
694   char **matching;
695
696   bfd_set_error (bfd_error_no_error);
697
698   target = NULL;
699
700   if (stat (archive_filename, &sbuf) != 0)
701     {
702 #ifndef __GO32__
703
704 /* KLUDGE ALERT! Temporary fix until I figger why
705  * stat() is wrong ... think it's buried in GO32's IDT
706  * - Jax
707  */
708       if (errno != ENOENT)
709         bfd_fatal (archive_filename);
710 #endif
711
712       if (!operation_alters_arch)
713         {
714           fprintf (stderr, "%s: ", program_name);
715           perror (archive_filename);
716           maybequit ();
717           return NULL;
718         }
719
720       /* Try to figure out the target to use for the archive from the
721          first object on the list.  */
722       if (file != NULL)
723         {
724           bfd *obj;
725
726           obj = bfd_openr (file, NULL);
727           if (obj != NULL)
728             {
729               if (bfd_check_format (obj, bfd_object))
730                 target = bfd_get_target (obj);
731               (void) bfd_close (obj);
732             }
733         }
734
735       /* Create an empty archive.  */
736       arch = bfd_openw (archive_filename, target);
737       if (arch == NULL
738           || ! bfd_set_format (arch, bfd_archive)
739           || ! bfd_close (arch))
740         bfd_fatal (archive_filename);
741
742       /* If we die creating a new archive, don't leave it around.  */
743       output_filename = archive_filename;
744     }
745
746   arch = bfd_openr (archive_filename, target);
747   if (arch == NULL)
748     {
749     bloser:
750       bfd_fatal (archive_filename);
751     }
752
753   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
754     {
755       bfd_nonfatal (archive_filename);
756       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
757         {
758           list_matching_formats (matching);
759           free (matching);
760         }
761       xexit (1);
762     }
763
764   last_one = &(arch->next);
765   /* Read all the contents right away, regardless.  */
766   for (next_one = bfd_openr_next_archived_file (arch, NULL);
767        next_one;
768        next_one = bfd_openr_next_archived_file (arch, next_one))
769     {
770       PROGRESS (1);
771       *last_one = next_one;
772       last_one = &next_one->next;
773     }
774   *last_one = (bfd *) NULL;
775   if (bfd_get_error () != bfd_error_no_more_archived_files)
776     goto bloser;
777   return arch;
778 }
779
780 static void
781 print_contents (abfd)
782      bfd *abfd;
783 {
784   int ncopied = 0;
785   char *cbuf = xmalloc (BUFSIZE);
786   struct stat buf;
787   long size;
788   if (bfd_stat_arch_elt (abfd, &buf) != 0)
789     /* xgettext:c-format */
790     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
791
792   if (verbose)
793     printf ("\n<%s>\n\n", bfd_get_filename (abfd));
794
795   bfd_seek (abfd, 0, SEEK_SET);
796
797   size = buf.st_size;
798   while (ncopied < size)
799     {
800
801       int nread;
802       int tocopy = size - ncopied;
803       if (tocopy > BUFSIZE)
804         tocopy = BUFSIZE;
805
806       nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke
807                                                            abstraction!  */
808       if (nread != tocopy)
809         /* xgettext:c-format */
810         fatal (_("%s is not a valid archive"),
811                bfd_get_filename (bfd_my_archive (abfd)));
812       fwrite (cbuf, 1, nread, stdout);
813       ncopied += tocopy;
814     }
815   free (cbuf);
816 }
817
818 /* Extract a member of the archive into its own file.
819
820    We defer opening the new file until after we have read a BUFSIZ chunk of the
821    old one, since we know we have just read the archive header for the old
822    one.  Since most members are shorter than BUFSIZ, this means we will read
823    the old header, read the old data, write a new inode for the new file, and
824    write the new data, and be done. This 'optimization' is what comes from
825    sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
826    Gilmore  */
827
828 void
829 extract_file (abfd)
830      bfd *abfd;
831 {
832   FILE *ostream;
833   char *cbuf = xmalloc (BUFSIZE);
834   int nread, tocopy;
835   long ncopied = 0;
836   long size;
837   struct stat buf;
838   
839   if (bfd_stat_arch_elt (abfd, &buf) != 0)
840     /* xgettext:c-format */
841     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
842   size = buf.st_size;
843
844   if (size < 0)
845     /* xgettext:c-format */
846     fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
847   
848   if (verbose)
849     printf ("x - %s\n", bfd_get_filename (abfd));
850
851   bfd_seek (abfd, 0, SEEK_SET);
852
853   ostream = NULL;
854   if (size == 0)
855     {
856       /* Seems like an abstraction violation, eh?  Well it's OK! */
857       output_filename = bfd_get_filename (abfd);
858
859       ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
860       if (ostream == NULL)
861         {
862           perror (bfd_get_filename (abfd));
863           xexit (1);
864         }
865
866       output_file = ostream;
867     }
868   else
869     while (ncopied < size)
870       {
871         tocopy = size - ncopied;
872         if (tocopy > BUFSIZE)
873           tocopy = BUFSIZE;
874
875         nread = bfd_read (cbuf, 1, tocopy, abfd);
876         if (nread != tocopy)
877           /* xgettext:c-format */
878           fatal (_("%s is not a valid archive"),
879                  bfd_get_filename (bfd_my_archive (abfd)));
880
881         /* See comment above; this saves disk arm motion */
882         if (ostream == NULL)
883           {
884             /* Seems like an abstraction violation, eh?  Well it's OK! */
885             output_filename = bfd_get_filename (abfd);
886
887             ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
888             if (ostream == NULL)
889               {
890                 perror (bfd_get_filename (abfd));
891                 xexit (1);
892               }
893
894             output_file = ostream;
895           }
896         fwrite (cbuf, 1, nread, ostream);
897         ncopied += tocopy;
898       }
899
900   if (ostream != NULL)
901     fclose (ostream);
902
903   output_file = NULL;
904   output_filename = NULL;
905
906   chmod (bfd_get_filename (abfd), buf.st_mode);
907
908   if (preserve_dates)
909     set_times (bfd_get_filename (abfd), &buf);
910
911   free (cbuf);
912 }
913
914 #if 0
915
916 /* We don't use this anymore.  Too many systems expect ar to rebuild
917    the symbol table even when q is used.  */
918
919 /* Just do it quickly; don't worry about dups, armap, or anything like that */
920
921 static void
922 do_quick_append (archive_filename, files_to_append)
923      const char *archive_filename;
924      char **files_to_append;
925 {
926   FILE *ofile, *ifile;
927   char *buf = xmalloc (BUFSIZE);
928   long tocopy, thistime;
929   bfd *temp;
930   struct stat sbuf;
931   boolean newfile = false;
932   bfd_set_error (bfd_error_no_error);
933
934   if (stat (archive_filename, &sbuf) != 0)
935     {
936
937 #ifndef __GO32__
938
939 /* KLUDGE ALERT! Temporary fix until I figger why
940  * stat() is wrong ... think it's buried in GO32's IDT
941  * - Jax
942  */
943
944       if (errno != ENOENT)
945         bfd_fatal (archive_filename);
946 #endif
947
948       newfile = true;
949     }
950
951   ofile = fopen (archive_filename, FOPEN_AUB);
952   if (ofile == NULL)
953     {
954       perror (program_name);
955       xexit (1);
956     }
957
958   temp = bfd_openr (archive_filename, NULL);
959   if (temp == NULL)
960     {
961       bfd_fatal (archive_filename);
962     }
963   if (newfile == false)
964     {
965       if (bfd_check_format (temp, bfd_archive) != true)
966         /* xgettext:c-format */
967         fatal (_("%s is not an archive"), archive_filename);
968     }
969   else
970     {
971       fwrite (ARMAG, 1, SARMAG, ofile);
972       if (!silent_create)
973         /* xgettext:c-format */
974         fprintf (stderr, _("%s: creating %s\n"),
975                  program_name, archive_filename);
976     }
977
978   if (ar_truncate)
979     temp->flags |= BFD_TRADITIONAL_FORMAT;
980
981   /* assume it's an achive, go straight to the end, sans $200 */
982   fseek (ofile, 0, 2);
983
984   for (; files_to_append && *files_to_append; ++files_to_append)
985     {
986       struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
987       if (hdr == NULL)
988         {
989           bfd_fatal (*files_to_append);
990         }
991
992       BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
993
994       ifile = fopen (*files_to_append, FOPEN_RB);
995       if (ifile == NULL)
996         {
997           bfd_nonfatal (*files_to_append);
998         }
999
1000       if (stat (*files_to_append, &sbuf) != 0)
1001         {
1002           bfd_nonfatal (*files_to_append);
1003         }
1004
1005       tocopy = sbuf.st_size;
1006
1007       /* XXX should do error-checking! */
1008       fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
1009
1010       while (tocopy > 0)
1011         {
1012           thistime = tocopy;
1013           if (thistime > BUFSIZE)
1014             thistime = BUFSIZE;
1015           fread (buf, 1, thistime, ifile);
1016           fwrite (buf, 1, thistime, ofile);
1017           tocopy -= thistime;
1018         }
1019       fclose (ifile);
1020       if ((sbuf.st_size % 2) == 1)
1021         putc ('\012', ofile);
1022     }
1023   fclose (ofile);
1024   bfd_close (temp);
1025   free (buf);
1026 }
1027
1028 #endif /* 0 */
1029
1030 static void
1031 write_archive (iarch)
1032      bfd *iarch;
1033 {
1034   bfd *obfd;
1035   char *old_name, *new_name;
1036   bfd *contents_head = iarch->next;
1037
1038   old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1039   strcpy (old_name, bfd_get_filename (iarch));
1040   new_name = make_tempname (old_name);
1041
1042   output_filename = new_name;
1043
1044   obfd = bfd_openw (new_name, bfd_get_target (iarch));
1045
1046   if (obfd == NULL)
1047     bfd_fatal (old_name);
1048
1049   output_bfd = obfd;
1050
1051   bfd_set_format (obfd, bfd_archive);
1052
1053   /* Request writing the archive symbol table unless we've
1054      been explicitly requested not to.  */
1055   obfd->has_armap = write_armap >= 0;
1056
1057   if (ar_truncate)
1058     {
1059       /* This should really use bfd_set_file_flags, but that rejects
1060          archives.  */
1061       obfd->flags |= BFD_TRADITIONAL_FORMAT;
1062     }
1063
1064   if (bfd_set_archive_head (obfd, contents_head) != true)
1065     bfd_fatal (old_name);
1066
1067   if (!bfd_close (obfd))
1068     bfd_fatal (old_name);
1069
1070   output_bfd = NULL;
1071   output_filename = NULL;
1072
1073   /* We don't care if this fails; we might be creating the archive.  */
1074   bfd_close (iarch);
1075
1076   if (smart_rename (new_name, old_name, 0) != 0)
1077     xexit (1);
1078 }
1079
1080 /* Return a pointer to the pointer to the entry which should be rplacd'd
1081    into when altering.  DEFAULT_POS should be how to interpret pos_default,
1082    and should be a pos value.  */
1083
1084 static bfd **
1085 get_pos_bfd (contents, default_pos, default_posname)
1086      bfd **contents;
1087      enum pos default_pos;
1088      const char *default_posname;
1089 {
1090   bfd **after_bfd = contents;
1091   enum pos realpos;
1092   const char *realposname;
1093
1094   if (postype == pos_default)
1095     {
1096       realpos = default_pos;
1097       realposname = default_posname;
1098     }
1099   else
1100     {
1101       realpos = postype;
1102       realposname = posname;
1103     }
1104
1105   if (realpos == pos_end)
1106     {
1107       while (*after_bfd)
1108         after_bfd = &((*after_bfd)->next);
1109     }
1110   else
1111     {
1112       for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1113         if (strcmp ((*after_bfd)->filename, realposname) == 0)
1114           {
1115             if (realpos == pos_after)
1116               after_bfd = &(*after_bfd)->next;
1117             break;
1118           }
1119     }
1120   return after_bfd;
1121 }
1122
1123 static void
1124 delete_members (arch, files_to_delete)
1125      bfd *arch;
1126      char **files_to_delete;
1127 {
1128   bfd **current_ptr_ptr;
1129   boolean found;
1130   boolean something_changed = false;
1131   int match_count;
1132
1133   for (; *files_to_delete != NULL; ++files_to_delete)
1134     {
1135       /* In a.out systems, the armap is optional.  It's also called
1136          __.SYMDEF.  So if the user asked to delete it, we should remember
1137          that fact. This isn't quite right for COFF systems (where
1138          __.SYMDEF might be regular member), but it's very unlikely
1139          to be a problem.  FIXME */
1140
1141       if (!strcmp (*files_to_delete, "__.SYMDEF"))
1142         {
1143           arch->has_armap = false;
1144           write_armap = -1;
1145           continue;
1146         }
1147
1148       found = false;
1149       match_count = 0;
1150       current_ptr_ptr = &(arch->next);
1151       while (*current_ptr_ptr)
1152         {
1153           if (strcmp (normalize (*files_to_delete, arch),
1154                       (*current_ptr_ptr)->filename) == 0)
1155             {
1156               ++match_count;
1157               if (counted_name_mode
1158                   && match_count != counted_name_counter) 
1159                 {
1160                   /* Counting, and didn't match on count; go on to the
1161                      next one.  */
1162                 }
1163               else
1164                 {
1165                   found = true;
1166                   something_changed = true;
1167                   if (verbose)
1168                     printf ("d - %s\n",
1169                             *files_to_delete);
1170                   *current_ptr_ptr = ((*current_ptr_ptr)->next);
1171                   goto next_file;
1172                 }
1173             }
1174
1175           current_ptr_ptr = &((*current_ptr_ptr)->next);
1176         }
1177
1178       if (verbose && found == false)
1179         {
1180           /* xgettext:c-format */
1181           printf (_("No member named `%s'\n"), *files_to_delete);
1182         }
1183     next_file:
1184       ;
1185     }
1186
1187   if (something_changed == true)
1188     write_archive (arch);
1189   else
1190     output_filename = NULL;
1191 }
1192
1193
1194 /* Reposition existing members within an archive */
1195
1196 static void
1197 move_members (arch, files_to_move)
1198      bfd *arch;
1199      char **files_to_move;
1200 {
1201   bfd **after_bfd;              /* New entries go after this one */
1202   bfd **current_ptr_ptr;        /* cdr pointer into contents */
1203
1204   for (; *files_to_move; ++files_to_move)
1205     {
1206       current_ptr_ptr = &(arch->next);
1207       while (*current_ptr_ptr)
1208         {
1209           bfd *current_ptr = *current_ptr_ptr;
1210           if (strcmp (normalize (*files_to_move, arch),
1211                       current_ptr->filename) == 0)
1212             {
1213               /* Move this file to the end of the list - first cut from
1214                  where it is.  */
1215               bfd *link;
1216               *current_ptr_ptr = current_ptr->next;
1217
1218               /* Now glue to end */
1219               after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1220               link = *after_bfd;
1221               *after_bfd = current_ptr;
1222               current_ptr->next = link;
1223
1224               if (verbose)
1225                 printf ("m - %s\n", *files_to_move);
1226
1227               goto next_file;
1228             }
1229
1230           current_ptr_ptr = &((*current_ptr_ptr)->next);
1231         }
1232       /* xgettext:c-format */
1233       fprintf (stderr, _("%s: no entry %s in archive %s!\n"),
1234                program_name, *files_to_move, arch->filename);
1235       xexit (1);
1236     next_file:;
1237     }
1238
1239   write_archive (arch);
1240 }
1241
1242 /* Ought to default to replacing in place, but this is existing practice!  */
1243
1244 static void
1245 replace_members (arch, files_to_move, quick)
1246      bfd *arch;
1247      char **files_to_move;
1248      boolean quick;
1249 {
1250   boolean changed = false;
1251   bfd **after_bfd;              /* New entries go after this one */
1252   bfd *current;
1253   bfd **current_ptr;
1254   bfd *temp;
1255
1256   while (files_to_move && *files_to_move)
1257     {
1258       if (! quick)
1259         {
1260           current_ptr = &arch->next;
1261           while (*current_ptr)
1262             {
1263               current = *current_ptr;
1264
1265               /* For compatibility with existing ar programs, we
1266                  permit the same file to be added multiple times.  */
1267               if (strcmp (normalize (*files_to_move, arch),
1268                           normalize (current->filename, arch)) == 0
1269                   && current->arelt_data != NULL)
1270                 {
1271                   if (newer_only)
1272                     {
1273                       struct stat fsbuf, asbuf;
1274
1275                       if (stat (*files_to_move, &fsbuf) != 0)
1276                         {
1277                           if (errno != ENOENT)
1278                             bfd_fatal (*files_to_move);
1279                           goto next_file;
1280                         }
1281                       if (bfd_stat_arch_elt (current, &asbuf) != 0)
1282                         /* xgettext:c-format */
1283                         fatal (_("internal stat error on %s"), current->filename);
1284
1285                       if (fsbuf.st_mtime <= asbuf.st_mtime)
1286                         goto next_file;
1287                     }
1288
1289                   after_bfd = get_pos_bfd (&arch->next, pos_after,
1290                                            current->filename);
1291                   temp = *after_bfd;
1292
1293                   *after_bfd = bfd_openr (*files_to_move, NULL);
1294                   if (*after_bfd == (bfd *) NULL)
1295                     {
1296                       bfd_fatal (*files_to_move);
1297                     }
1298                   (*after_bfd)->next = temp;
1299
1300                   /* snip out this entry from the chain */
1301                   *current_ptr = (*current_ptr)->next;
1302
1303                   if (verbose)
1304                     {
1305                       printf ("r - %s\n", *files_to_move);
1306                     }
1307
1308                   changed = true;
1309
1310                   goto next_file;
1311                 }
1312               current_ptr = &(current->next);
1313             }
1314         }
1315
1316       /* Add to the end of the archive.  */
1317
1318       after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1319       temp = *after_bfd;
1320       *after_bfd = bfd_openr (*files_to_move, NULL);
1321       if (*after_bfd == (bfd *) NULL)
1322         {
1323           bfd_fatal (*files_to_move);
1324         }
1325       if (verbose)
1326         {
1327           printf ("a - %s\n", *files_to_move);
1328         }
1329
1330       (*after_bfd)->next = temp;
1331
1332       changed = true;
1333
1334     next_file:;
1335
1336       files_to_move++;
1337     }
1338
1339   if (changed)
1340     write_archive (arch);
1341   else
1342     output_filename = NULL;
1343 }
1344
1345 static void
1346 ranlib_only (archname)
1347      const char *archname;
1348 {
1349   bfd *arch;
1350
1351   write_armap = 1;
1352   arch = open_inarch (archname, (char *) NULL);
1353   if (arch == NULL)
1354     xexit (1);
1355   write_archive (arch);
1356 }
1357
1358 /* Update the timestamp of the symbol map of an archive.  */
1359
1360 static void
1361 ranlib_touch (archname)
1362      const char *archname;
1363 {
1364 #ifdef __GO32__
1365   /* I don't think updating works on go32.  */
1366   ranlib_only (archname);
1367 #else
1368   int f;
1369   bfd *arch;
1370   char **matching;
1371
1372   f = open (archname, O_RDWR | O_BINARY, 0);
1373   if (f < 0)
1374     {
1375       bfd_set_error (bfd_error_system_call);
1376       bfd_fatal (archname);
1377     }
1378
1379   arch = bfd_fdopenr (archname, (const char *) NULL, f);
1380   if (arch == NULL)
1381     bfd_fatal (archname);
1382   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1383     {
1384       bfd_nonfatal (archname);
1385       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1386         {
1387           list_matching_formats (matching);
1388           free (matching);
1389         }
1390       xexit (1);
1391     }
1392
1393   if (! bfd_has_map (arch))
1394     /* xgettext:c-format */
1395     fatal (_("%s: no archive map to update"), archname);
1396
1397   bfd_update_armap_timestamp (arch);
1398
1399   if (! bfd_close (arch))
1400     bfd_fatal (archname);
1401 #endif
1402 }
1403
1404 /* Things which are interesting to map over all or some of the files: */
1405
1406 static void
1407 print_descr (abfd)
1408      bfd *abfd;
1409 {
1410   print_arelt_descr (stdout, abfd, verbose);
1411 }