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