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