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