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