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