This commit was generated by cvs2svn to track changes on a CVS vendor
[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   setlocale (LC_MESSAGES, "");
315   bindtextdomain (PACKAGE, LOCALEDIR);
316   textdomain (PACKAGE);
317
318   program_name = argv[0];
319   xmalloc_set_program_name (program_name);
320
321   if (is_ranlib < 0)
322     {
323       char *temp;
324
325       temp = strrchr (program_name, '/');
326       if (temp == NULL)
327         temp = program_name;
328       else
329         ++temp;
330       if (strlen (temp) >= 6
331           && strcmp (temp + strlen (temp) - 6, "ranlib") == 0)
332         is_ranlib = 1;
333       else
334         is_ranlib = 0;
335     }
336
337   if (argc > 1 && argv[1][0] == '-')
338     {
339       if (strcmp (argv[1], "--help") == 0)
340         usage (1);
341       else if (strcmp (argv[1], "--version") == 0)
342         {
343           if (is_ranlib)
344             print_version ("ranlib");
345           else
346             print_version ("ar");
347         }
348     }
349
350   START_PROGRESS (program_name, 0);
351
352   bfd_init ();
353   set_default_bfd_target ();
354
355   show_version = 0;
356
357   xatexit (remove_output);
358
359   if (is_ranlib)
360     {
361       boolean touch = false;
362
363       if (argc < 2 || strcmp (argv[1], "--help") == 0)
364         usage (0);
365       if (strcmp (argv[1], "-V") == 0
366           || strcmp (argv[1], "-v") == 0
367           || strncmp (argv[1], "--v", 3) == 0)
368         print_version ("ranlib");
369       arg_index = 1;
370       if (strcmp (argv[1], "-t") == 0)
371         {
372           ++arg_index;
373           touch = true;
374         }
375       while (arg_index < argc)
376         {
377           if (! touch)
378             ranlib_only (argv[arg_index]);
379           else
380             ranlib_touch (argv[arg_index]);
381           ++arg_index;
382         }
383       xexit (0);
384     }
385
386   if (argc == 2 && strcmp (argv[1], "-M") == 0)
387     {
388       mri_emul ();
389       xexit (0);
390     }
391
392   if (argc < 2)
393     usage (0);
394
395   arg_ptr = argv[1];
396
397   if (*arg_ptr == '-')
398     ++arg_ptr;                  /* compatibility */
399
400   while ((c = *arg_ptr++) != '\0')
401     {
402       switch (c)
403         {
404         case 'd':
405         case 'm':
406         case 'p':
407         case 'q':
408         case 'r':
409         case 't':
410         case 'x':
411           if (operation != none)
412             fatal (_("two different operation options specified"));
413           switch (c)
414             {
415             case 'd':
416               operation = delete;
417               operation_alters_arch = true;
418               break;
419             case 'm':
420               operation = move;
421               operation_alters_arch = true;
422               break;
423             case 'p':
424               operation = print_files;
425               break;
426             case 'q':
427               operation = quick_append;
428               operation_alters_arch = true;
429               break;
430             case 'r':
431               operation = replace;
432               operation_alters_arch = true;
433               break;
434             case 't':
435               operation = print_table;
436               break;
437             case 'x':
438               operation = extract;
439               break;
440             }
441         case 'l':
442           break;
443         case 'c':
444           silent_create = 1;
445           break;
446         case 'o':
447           preserve_dates = 1;
448           break;
449         case 'V':
450           show_version = true;
451           break;
452         case 's':
453           write_armap = 1;
454           break;
455         case 'S':
456           write_armap = -1;
457           break;
458         case 'u':
459           newer_only = 1;
460           break;
461         case 'v':
462           verbose = 1;
463           break;
464         case 'a':
465           postype = pos_after;
466           break;
467         case 'b':
468           postype = pos_before;
469           break;
470         case 'i':
471           postype = pos_before;
472           break;
473         case 'M':
474           mri_mode = 1;
475           break;
476         case 'f':
477           ar_truncate = true;
478           break;
479         default:
480           fprintf (stderr, _("%s: illegal option -- %c\n"), program_name, c);
481           usage (0);
482         }
483     }
484
485   if (show_version)
486     print_version ("ar");
487
488   if (argc < 3)
489     usage (0);
490
491   if (mri_mode)
492     {
493       mri_emul ();
494     }
495   else
496     {
497       bfd *arch;
498
499       /* We can't write an armap when using ar q, so just do ar r
500          instead.  */
501       if (operation == quick_append && write_armap)
502         operation = replace;
503
504       if ((operation == none || operation == print_table)
505           && write_armap == 1)
506         {
507           ranlib_only (argv[2]);
508           xexit (0);
509         }
510
511       if (operation == none)
512         fatal (_("no operation specified"));
513
514       if (newer_only && operation != replace)
515         fatal (_("`u' is only meaningful with the `r' option."));
516
517       arg_index = 2;
518
519       if (postype != pos_default)
520         posname = argv[arg_index++];
521
522       inarch_filename = argv[arg_index++];
523
524       files = arg_index < argc ? argv + arg_index : NULL;
525
526 #if 0
527       /* We don't use do_quick_append any more.  Too many systems
528          expect ar to always rebuild the symbol table even when q is
529          used.  */
530
531       /* We can't do a quick append if we need to construct an
532          extended name table, because do_quick_append won't be able to
533          rebuild the name table.  Unfortunately, at this point we
534          don't actually know the maximum name length permitted by this
535          object file format.  So, we guess.  FIXME.  */
536       if (operation == quick_append && ! ar_truncate)
537         {
538           char **chk;
539
540           for (chk = files; chk != NULL && *chk != '\0'; chk++)
541             {
542               if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
543                 {
544                   operation = replace;
545                   break;
546                 }
547             }
548         }
549
550       if (operation == quick_append)
551         {
552           /* Note that quick appending to a non-existent archive creates it,
553              even if there are no files to append. */
554           do_quick_append (inarch_filename, files);
555           xexit (0);
556         }
557 #endif
558
559       arch = open_inarch (inarch_filename,
560                           files == NULL ? (char *) NULL : files[0]);
561
562       switch (operation)
563         {
564         case print_table:
565           map_over_members (arch, print_descr, files, argc - 3);
566           break;
567
568         case print_files:
569           map_over_members (arch, print_contents, files, argc - 3);
570           break;
571
572         case extract:
573           map_over_members (arch, extract_file, files, argc - 3);
574           break;
575
576         case delete:
577           if (files != NULL)
578             delete_members (arch, files);
579           break;
580
581         case move:
582           if (files != NULL)
583             move_members (arch, files);
584           break;
585
586         case replace:
587         case quick_append:
588           if (files != NULL || write_armap > 0)
589             replace_members (arch, files, operation == quick_append);
590           break;
591
592           /* Shouldn't happen! */
593         default:
594           fprintf (stderr, _("%s: internal error -- this option not implemented\n"),
595                    program_name);
596           xexit (1);
597         }
598     }
599
600   END_PROGRESS (program_name);
601
602   xexit (0);
603   return 0;
604 }
605
606 bfd *
607 open_inarch (archive_filename, file)
608      const char *archive_filename;
609      const char *file;
610 {
611   const char *target;
612   bfd **last_one;
613   bfd *next_one;
614   struct stat sbuf;
615   bfd *arch;
616   char **matching;
617
618   bfd_set_error (bfd_error_no_error);
619
620   target = NULL;
621
622   if (stat (archive_filename, &sbuf) != 0)
623     {
624 #ifndef __GO32__
625
626 /* KLUDGE ALERT! Temporary fix until I figger why
627  * stat() is wrong ... think it's buried in GO32's IDT
628  * - Jax
629  */
630       if (errno != ENOENT)
631         bfd_fatal (archive_filename);
632 #endif
633
634       if (!operation_alters_arch)
635         {
636           fprintf (stderr, "%s: ", program_name);
637           perror (archive_filename);
638           maybequit ();
639           return NULL;
640         }
641
642       /* Try to figure out the target to use for the archive from the
643          first object on the list.  */
644       if (file != NULL)
645         {
646           bfd *obj;
647
648           obj = bfd_openr (file, NULL);
649           if (obj != NULL)
650             {
651               if (bfd_check_format (obj, bfd_object))
652                 target = bfd_get_target (obj);
653               (void) bfd_close (obj);
654             }
655         }
656
657       /* Create an empty archive.  */
658       arch = bfd_openw (archive_filename, target);
659       if (arch == NULL
660           || ! bfd_set_format (arch, bfd_archive)
661           || ! bfd_close (arch))
662         bfd_fatal (archive_filename);
663     }
664
665   arch = bfd_openr (archive_filename, target);
666   if (arch == NULL)
667     {
668     bloser:
669       bfd_fatal (archive_filename);
670     }
671
672   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
673     {
674       bfd_nonfatal (archive_filename);
675       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
676         {
677           list_matching_formats (matching);
678           free (matching);
679         }
680       xexit (1);
681     }
682
683   last_one = &(arch->next);
684   /* Read all the contents right away, regardless.  */
685   for (next_one = bfd_openr_next_archived_file (arch, NULL);
686        next_one;
687        next_one = bfd_openr_next_archived_file (arch, next_one))
688     {
689       PROGRESS (1);
690       *last_one = next_one;
691       last_one = &next_one->next;
692     }
693   *last_one = (bfd *) NULL;
694   if (bfd_get_error () != bfd_error_no_more_archived_files)
695     goto bloser;
696   return arch;
697 }
698
699 static void
700 print_contents (abfd)
701      bfd *abfd;
702 {
703   int ncopied = 0;
704   char *cbuf = xmalloc (BUFSIZE);
705   struct stat buf;
706   long size;
707   if (bfd_stat_arch_elt (abfd, &buf) != 0)
708     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
709
710   if (verbose)
711     printf (_("\n<member %s>\n\n"), bfd_get_filename (abfd));
712
713   bfd_seek (abfd, 0, SEEK_SET);
714
715   size = buf.st_size;
716   while (ncopied < size)
717     {
718
719       int nread;
720       int tocopy = size - ncopied;
721       if (tocopy > BUFSIZE)
722         tocopy = BUFSIZE;
723
724       nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke
725                                                            abstraction!  */
726       if (nread != tocopy)
727         fatal (_("%s is not a valid archive"),
728                bfd_get_filename (bfd_my_archive (abfd)));
729       fwrite (cbuf, 1, nread, stdout);
730       ncopied += tocopy;
731     }
732   free (cbuf);
733 }
734
735 /* Extract a member of the archive into its own file.
736
737    We defer opening the new file until after we have read a BUFSIZ chunk of the
738    old one, since we know we have just read the archive header for the old
739    one.  Since most members are shorter than BUFSIZ, this means we will read
740    the old header, read the old data, write a new inode for the new file, and
741    write the new data, and be done. This 'optimization' is what comes from
742    sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
743    Gilmore  */
744
745 void
746 extract_file (abfd)
747      bfd *abfd;
748 {
749   FILE *ostream;
750   char *cbuf = xmalloc (BUFSIZE);
751   int nread, tocopy;
752   int ncopied = 0;
753   long size;
754   struct stat buf;
755   if (bfd_stat_arch_elt (abfd, &buf) != 0)
756     fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
757   size = buf.st_size;
758
759   if (verbose)
760     printf ("x - %s\n", bfd_get_filename (abfd));
761
762   bfd_seek (abfd, 0, SEEK_SET);
763
764   ostream = 0;
765   if (size == 0)
766     {
767       /* Seems like an abstraction violation, eh?  Well it's OK! */
768       output_filename = bfd_get_filename (abfd);
769
770       ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
771       if (!ostream)
772         {
773           perror (bfd_get_filename (abfd));
774           xexit (1);
775         }
776
777       output_file = ostream;
778     }
779   else
780     while (ncopied < size)
781       {
782         tocopy = size - ncopied;
783         if (tocopy > BUFSIZE)
784           tocopy = BUFSIZE;
785
786         nread = bfd_read (cbuf, 1, tocopy, abfd);
787         if (nread != tocopy)
788           fatal (_("%s is not a valid archive"),
789                  bfd_get_filename (bfd_my_archive (abfd)));
790
791         /* See comment above; this saves disk arm motion */
792         if (!ostream)
793           {
794             /* Seems like an abstraction violation, eh?  Well it's OK! */
795             output_filename = bfd_get_filename (abfd);
796
797             ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
798             if (!ostream)
799               {
800                 perror (bfd_get_filename (abfd));
801                 xexit (1);
802               }
803
804             output_file = ostream;
805           }
806         fwrite (cbuf, 1, nread, ostream);
807         ncopied += tocopy;
808       }
809
810   fclose (ostream);
811
812   output_file = NULL;
813   output_filename = NULL;
814
815   chmod (bfd_get_filename (abfd), buf.st_mode);
816
817   if (preserve_dates)
818     {
819 #ifdef HAVE_GOOD_UTIME_H
820       struct utimbuf tb;
821       tb.actime = buf.st_mtime;
822       tb.modtime = buf.st_mtime;
823       utime (bfd_get_filename (abfd), &tb);     /* FIXME check result */
824 #else /* ! HAVE_GOOD_UTIME_H */
825 #ifndef HAVE_UTIMES
826       long tb[2];
827       tb[0] = buf.st_mtime;
828       tb[1] = buf.st_mtime;
829       utime (bfd_get_filename (abfd), tb);      /* FIXME check result */
830 #else /* HAVE_UTIMES */
831       struct timeval tv[2];
832       tv[0].tv_sec = buf.st_mtime;
833       tv[0].tv_usec = 0;
834       tv[1].tv_sec = buf.st_mtime;
835       tv[1].tv_usec = 0;
836       utimes (bfd_get_filename (abfd), tv);     /* FIXME check result */
837 #endif /* HAVE_UTIMES */
838 #endif /* ! HAVE_GOOD_UTIME_H */
839     }
840 free (cbuf);
841 }
842
843 #if 0
844
845 /* We don't use this anymore.  Too many systems expect ar to rebuild
846    the symbol table even when q is used.  */
847
848 /* Just do it quickly; don't worry about dups, armap, or anything like that */
849
850 static void
851 do_quick_append (archive_filename, files_to_append)
852      const char *archive_filename;
853      char **files_to_append;
854 {
855   FILE *ofile, *ifile;
856   char *buf = xmalloc (BUFSIZE);
857   long tocopy, thistime;
858   bfd *temp;
859   struct stat sbuf;
860   boolean newfile = false;
861   bfd_set_error (bfd_error_no_error);
862
863   if (stat (archive_filename, &sbuf) != 0)
864     {
865
866 #ifndef __GO32__
867
868 /* KLUDGE ALERT! Temporary fix until I figger why
869  * stat() is wrong ... think it's buried in GO32's IDT
870  * - Jax
871  */
872
873       if (errno != ENOENT)
874         bfd_fatal (archive_filename);
875 #endif
876
877       newfile = true;
878     }
879
880   ofile = fopen (archive_filename, FOPEN_AUB);
881   if (ofile == NULL)
882     {
883       perror (program_name);
884       xexit (1);
885     }
886
887   temp = bfd_openr (archive_filename, NULL);
888   if (temp == NULL)
889     {
890       bfd_fatal (archive_filename);
891     }
892   if (newfile == false)
893     {
894       if (bfd_check_format (temp, bfd_archive) != true)
895         fatal (_("%s is not an archive"), archive_filename);
896     }
897   else
898     {
899       fwrite (ARMAG, 1, SARMAG, ofile);
900       if (!silent_create)
901         fprintf (stderr, _("%s: creating %s\n"),
902                  program_name, archive_filename);
903     }
904
905   if (ar_truncate)
906     temp->flags |= BFD_TRADITIONAL_FORMAT;
907
908   /* assume it's an achive, go straight to the end, sans $200 */
909   fseek (ofile, 0, 2);
910
911   for (; files_to_append && *files_to_append; ++files_to_append)
912     {
913       struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
914       if (hdr == NULL)
915         {
916           bfd_fatal (*files_to_append);
917         }
918
919       BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
920
921       ifile = fopen (*files_to_append, FOPEN_RB);
922       if (ifile == NULL)
923         {
924           bfd_nonfatal (*files_to_append);
925         }
926
927       if (stat (*files_to_append, &sbuf) != 0)
928         {
929           bfd_nonfatal (*files_to_append);
930         }
931
932       tocopy = sbuf.st_size;
933
934       /* XXX should do error-checking! */
935       fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
936
937       while (tocopy > 0)
938         {
939           thistime = tocopy;
940           if (thistime > BUFSIZE)
941             thistime = BUFSIZE;
942           fread (buf, 1, thistime, ifile);
943           fwrite (buf, 1, thistime, ofile);
944           tocopy -= thistime;
945         }
946       fclose (ifile);
947       if ((sbuf.st_size % 2) == 1)
948         putc ('\012', ofile);
949     }
950   fclose (ofile);
951   bfd_close (temp);
952   free (buf);
953 }
954
955 #endif /* 0 */
956
957 static void
958 write_archive (iarch)
959      bfd *iarch;
960 {
961   bfd *obfd;
962   char *old_name, *new_name;
963   bfd *contents_head = iarch->next;
964
965   old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
966   strcpy (old_name, bfd_get_filename (iarch));
967   new_name = make_tempname (old_name);
968
969   output_filename = new_name;
970
971   obfd = bfd_openw (new_name, bfd_get_target (iarch));
972
973   if (obfd == NULL)
974     bfd_fatal (old_name);
975
976   output_bfd = obfd;
977
978   bfd_set_format (obfd, bfd_archive);
979
980   /* Request writing the archive symbol table unless we've
981      been explicitly requested not to.  */
982   obfd->has_armap = write_armap >= 0;
983
984   if (ar_truncate)
985     {
986       /* This should really use bfd_set_file_flags, but that rejects
987          archives.  */
988       obfd->flags |= BFD_TRADITIONAL_FORMAT;
989     }
990
991   if (bfd_set_archive_head (obfd, contents_head) != true)
992     bfd_fatal (old_name);
993
994   if (!bfd_close (obfd))
995     bfd_fatal (old_name);
996
997   output_bfd = NULL;
998   output_filename = NULL;
999
1000   /* We don't care if this fails; we might be creating the archive.  */
1001   bfd_close (iarch);
1002   unlink (old_name);
1003
1004   if (rename (new_name, old_name) != 0)
1005     bfd_fatal (old_name);
1006 }
1007
1008 /* Return a pointer to the pointer to the entry which should be rplacd'd
1009    into when altering.  DEFAULT_POS should be how to interpret pos_default,
1010    and should be a pos value.  */
1011
1012 static bfd **
1013 get_pos_bfd (contents, default_pos, default_posname)
1014      bfd **contents;
1015      enum pos default_pos;
1016      const char *default_posname;
1017 {
1018   bfd **after_bfd = contents;
1019   enum pos realpos;
1020   const char *realposname;
1021
1022   if (postype == pos_default)
1023     {
1024       realpos = default_pos;
1025       realposname = default_posname;
1026     }
1027   else
1028     {
1029       realpos = postype;
1030       realposname = posname;
1031     }
1032
1033   if (realpos == pos_end)
1034     {
1035       while (*after_bfd)
1036         after_bfd = &((*after_bfd)->next);
1037     }
1038   else
1039     {
1040       for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1041         if (strcmp ((*after_bfd)->filename, realposname) == 0)
1042           {
1043             if (realpos == pos_after)
1044               after_bfd = &(*after_bfd)->next;
1045             break;
1046           }
1047     }
1048   return after_bfd;
1049 }
1050
1051 static void
1052 delete_members (arch, files_to_delete)
1053      bfd *arch;
1054      char **files_to_delete;
1055 {
1056   bfd **current_ptr_ptr;
1057   boolean found;
1058   boolean something_changed = false;
1059   for (; *files_to_delete != NULL; ++files_to_delete)
1060     {
1061       /* In a.out systems, the armap is optional.  It's also called
1062          __.SYMDEF.  So if the user asked to delete it, we should remember
1063          that fact. This isn't quite right for COFF systems (where
1064          __.SYMDEF might be regular member), but it's very unlikely
1065          to be a problem.  FIXME */
1066
1067       if (!strcmp (*files_to_delete, "__.SYMDEF"))
1068         {
1069           arch->has_armap = false;
1070           write_armap = -1;
1071           continue;
1072         }
1073
1074       found = false;
1075       current_ptr_ptr = &(arch->next);
1076       while (*current_ptr_ptr)
1077         {
1078           if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0)
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)->next);
1086               goto next_file;
1087             }
1088           else
1089             {
1090               current_ptr_ptr = &((*current_ptr_ptr)->next);
1091             }
1092         }
1093
1094       if (verbose && found == false)
1095         {
1096           printf (_("No member named `%s'\n"), *files_to_delete);
1097         }
1098     next_file:
1099       ;
1100     }
1101
1102   if (something_changed == true)
1103     {
1104       write_archive (arch);
1105     }
1106 }
1107
1108
1109 /* Reposition existing members within an archive */
1110
1111 static void
1112 move_members (arch, files_to_move)
1113      bfd *arch;
1114      char **files_to_move;
1115 {
1116   bfd **after_bfd;              /* New entries go after this one */
1117   bfd **current_ptr_ptr;        /* cdr pointer into contents */
1118
1119   for (; *files_to_move; ++files_to_move)
1120     {
1121       current_ptr_ptr = &(arch->next);
1122       while (*current_ptr_ptr)
1123         {
1124           bfd *current_ptr = *current_ptr_ptr;
1125           if (strcmp (normalize (*files_to_move, arch),
1126                       current_ptr->filename) == 0)
1127             {
1128               /* Move this file to the end of the list - first cut from
1129                  where it is.  */
1130               bfd *link;
1131               *current_ptr_ptr = current_ptr->next;
1132
1133               /* Now glue to end */
1134               after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1135               link = *after_bfd;
1136               *after_bfd = current_ptr;
1137               current_ptr->next = link;
1138
1139               if (verbose)
1140                 printf ("m - %s\n", *files_to_move);
1141
1142               goto next_file;
1143             }
1144
1145           current_ptr_ptr = &((*current_ptr_ptr)->next);
1146         }
1147       fprintf (stderr, _("%s: no entry %s in archive %s!\n"),
1148                program_name, *files_to_move, arch->filename);
1149       xexit (1);
1150     next_file:;
1151     }
1152
1153   write_archive (arch);
1154 }
1155
1156 /* Ought to default to replacing in place, but this is existing practice!  */
1157
1158 static void
1159 replace_members (arch, files_to_move, quick)
1160      bfd *arch;
1161      char **files_to_move;
1162      boolean quick;
1163 {
1164   boolean changed = false;
1165   bfd **after_bfd;              /* New entries go after this one */
1166   bfd *current;
1167   bfd **current_ptr;
1168   bfd *temp;
1169
1170   while (files_to_move && *files_to_move)
1171     {
1172       if (! quick)
1173         {
1174           current_ptr = &arch->next;
1175           while (*current_ptr)
1176             {
1177               current = *current_ptr;
1178
1179               /* For compatibility with existing ar programs, we
1180                  permit the same file to be added multiple times.  */
1181               if (strcmp (normalize (*files_to_move, arch),
1182                           normalize (current->filename, arch)) == 0
1183                   && current->arelt_data != NULL)
1184                 {
1185                   if (newer_only)
1186                     {
1187                       struct stat fsbuf, asbuf;
1188
1189                       if (stat (*files_to_move, &fsbuf) != 0)
1190                         {
1191                           if (errno != ENOENT)
1192                             bfd_fatal (*files_to_move);
1193                           goto next_file;
1194                         }
1195                       if (bfd_stat_arch_elt (current, &asbuf) != 0)
1196                         fatal (_("internal stat error on %s"), current->filename);
1197
1198                       if (fsbuf.st_mtime <= asbuf.st_mtime)
1199                         goto next_file;
1200                     }
1201
1202                   after_bfd = get_pos_bfd (&arch->next, pos_after,
1203                                            current->filename);
1204                   temp = *after_bfd;
1205
1206                   *after_bfd = bfd_openr (*files_to_move, NULL);
1207                   if (*after_bfd == (bfd *) NULL)
1208                     {
1209                       bfd_fatal (*files_to_move);
1210                     }
1211                   (*after_bfd)->next = temp;
1212
1213                   /* snip out this entry from the chain */
1214                   *current_ptr = (*current_ptr)->next;
1215
1216                   if (verbose)
1217                     {
1218                       printf ("r - %s\n", *files_to_move);
1219                     }
1220
1221                   changed = true;
1222
1223                   goto next_file;
1224                 }
1225               current_ptr = &(current->next);
1226             }
1227         }
1228
1229       /* Add to the end of the archive.  */
1230
1231       after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1232       temp = *after_bfd;
1233       *after_bfd = bfd_openr (*files_to_move, NULL);
1234       if (*after_bfd == (bfd *) NULL)
1235         {
1236           bfd_fatal (*files_to_move);
1237         }
1238       if (verbose)
1239         {
1240           printf ("a - %s\n", *files_to_move);
1241         }
1242
1243       (*after_bfd)->next = temp;
1244
1245       changed = true;
1246
1247     next_file:;
1248
1249       files_to_move++;
1250     }
1251
1252   if (changed)
1253     write_archive (arch);
1254 }
1255
1256 static void
1257 ranlib_only (archname)
1258      const char *archname;
1259 {
1260   bfd *arch;
1261
1262   write_armap = 1;
1263   arch = open_inarch (archname, (char *) NULL);
1264   if (arch == NULL)
1265     xexit (1);
1266   write_archive (arch);
1267 }
1268
1269 /* Update the timestamp of the symbol map of an archive.  */
1270
1271 static void
1272 ranlib_touch (archname)
1273      const char *archname;
1274 {
1275 #ifdef __GO32__
1276   /* I don't think updating works on go32.  */
1277   ranlib_only (archname);
1278 #else
1279   int f;
1280   bfd *arch;
1281   char **matching;
1282
1283   f = open (archname, O_RDWR, 0);
1284   if (f < 0)
1285     {
1286       bfd_set_error (bfd_error_system_call);
1287       bfd_fatal (archname);
1288     }
1289
1290   arch = bfd_fdopenr (archname, (const char *) NULL, f);
1291   if (arch == NULL)
1292     bfd_fatal (archname);
1293   if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1294     {
1295       bfd_nonfatal (archname);
1296       if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1297         {
1298           list_matching_formats (matching);
1299           free (matching);
1300         }
1301       xexit (1);
1302     }
1303
1304   if (! bfd_has_map (arch))
1305     fatal (_("%s: no archive map to update"), archname);
1306
1307   bfd_update_armap_timestamp (arch);
1308
1309   if (! bfd_close (arch))
1310     bfd_fatal (archname);
1311 #endif
1312 }
1313
1314 /* Things which are interesting to map over all or some of the files: */
1315
1316 static void
1317 print_descr (abfd)
1318      bfd *abfd;
1319 {
1320   print_arelt_descr (stdout, abfd, verbose);
1321 }