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