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