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