* COP2 testing changes.
[binutils-gdb.git] / binutils / ar.c
blob7d431c4627ed65b5688afb9573b8e70bf7e367b9
1 /* ar.c - Archive modify and extract.
2 Copyright 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
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.
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.
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. */
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.
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>
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 */
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
50 #define BUFSIZE 8192
52 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
54 struct ar_hdr *
55 bfd_special_undocumented_glue PARAMS ((bfd * abfd, char *filename));
57 /* Forward declarations */
59 static const char *
60 normalize PARAMS ((const char *, bfd *));
62 static void
63 remove_output PARAMS ((void));
65 static void
66 map_over_members PARAMS ((bfd *, void (*)(bfd *), char **, int));
68 static void
69 print_contents PARAMS ((bfd * member));
71 static void
72 delete_members PARAMS ((bfd *, char **files_to_delete));
74 #if 0
75 static void
76 do_quick_append PARAMS ((const char *archive_filename,
77 char **files_to_append));
78 #endif
80 static void
81 move_members PARAMS ((bfd *, char **files_to_move));
83 static void
84 replace_members PARAMS ((bfd *, char **files_to_replace, boolean quick));
86 static void
87 print_descr PARAMS ((bfd * abfd));
89 static void
90 write_archive PARAMS ((bfd *));
92 static void
93 ranlib_only PARAMS ((const char *archname));
95 static void
96 ranlib_touch PARAMS ((const char *archname));
98 /** Globals and flags */
100 int mri_mode;
102 /* This flag distinguishes between ar and ranlib:
103 1 means this is 'ranlib'; 0 means this is 'ar'.
104 -1 means if we should use argv[0] to decide. */
105 extern int is_ranlib;
107 /* Nonzero means don't warn about creating the archive file if necessary. */
108 int silent_create = 0;
110 /* Nonzero means describe each action performed. */
111 int verbose = 0;
113 /* Nonzero means preserve dates of members when extracting them. */
114 int preserve_dates = 0;
116 /* Nonzero means don't replace existing members whose dates are more recent
117 than the corresponding files. */
118 int newer_only = 0;
120 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
121 member). -1 means we've been explicitly asked to not write a symbol table;
122 +1 means we've been explictly asked to write it;
123 0 is the default.
124 Traditionally, the default in BSD has been to not write the table.
125 However, for POSIX.2 compliance the default is now to write a symbol table
126 if any of the members are object files. */
127 int write_armap = 0;
129 /* Nonzero means it's the name of an existing member; position new or moved
130 files with respect to this one. */
131 char *posname = NULL;
133 /* Sez how to use `posname': pos_before means position before that member.
134 pos_after means position after that member. pos_end means always at end.
135 pos_default means default appropriately. For the latter two, `posname'
136 should also be zero. */
137 enum pos
139 pos_default, pos_before, pos_after, pos_end
140 } postype = pos_default;
142 /* Whether to truncate names of files stored in the archive. */
143 static boolean ar_truncate = false;
145 int interactive = 0;
147 void
148 mri_emul ()
150 interactive = isatty (fileno (stdin));
151 yyparse ();
154 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
155 COUNT is the length of the FILES chain; FUNCTION is called on each entry
156 whose name matches one in FILES. */
158 static void
159 map_over_members (arch, function, files, count)
160 bfd *arch;
161 void (*function) PARAMS ((bfd *));
162 char **files;
163 int count;
165 bfd *head;
167 if (count == 0)
169 for (head = arch->next; head; head = head->next)
171 PROGRESS (1);
172 function (head);
174 return;
176 /* This may appear to be a baroque way of accomplishing what we want.
177 However we have to iterate over the filenames in order to notice where
178 a filename is requested but does not exist in the archive. Ditto
179 mapping over each file each time -- we want to hack multiple
180 references. */
182 for (; count > 0; files++, count--)
184 boolean found = false;
186 for (head = arch->next; head; head = head->next)
188 PROGRESS (1);
189 if (head->filename == NULL)
191 /* Some archive formats don't get the filenames filled in
192 until the elements are opened. */
193 struct stat buf;
194 bfd_stat_arch_elt (head, &buf);
196 if ((head->filename != NULL) &&
197 (!strcmp (*files, head->filename)))
199 found = true;
200 function (head);
203 if (!found)
204 fprintf (stderr, "no entry %s in archive\n", *files);
208 boolean operation_alters_arch = false;
210 void
211 usage (help)
212 int help;
214 FILE *s;
216 s = help ? stdout : stderr;
217 if (! is_ranlib)
218 fprintf (s, "\
219 Usage: %s [-]{dmpqrtx}[abcilosuvV] [member-name] archive-file file...\n\
220 %s -M [<mri-script]\n",
221 program_name, program_name);
222 else
223 fprintf (s, "\
224 Usage: %s [-vV] archive\n", program_name);
226 list_supported_targets (program_name, stderr);
228 if (help)
229 fprintf (s, "Report bugs to bug-gnu-utils@prep.ai.mit.edu\n");
231 xexit (help ? 0 : 1);
234 /* Normalize a file name specified on the command line into a file
235 name which we will use in an archive. */
237 static const char *
238 normalize (file, abfd)
239 const char *file;
240 bfd *abfd;
242 const char *filename;
244 filename = strrchr (file, '/');
245 if (filename != (char *) NULL)
246 filename++;
247 else
248 filename = file;
250 if (ar_truncate
251 && abfd != NULL
252 && strlen (filename) > abfd->xvec->ar_max_namelen)
254 char *s;
256 /* Space leak. */
257 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
258 memcpy (s, filename, abfd->xvec->ar_max_namelen);
259 s[abfd->xvec->ar_max_namelen] = '\0';
260 filename = s;
263 return filename;
266 /* Remove any output file. This is only called via xatexit. */
268 static char *output_filename = NULL;
269 static FILE *output_file = NULL;
270 static bfd *output_bfd = NULL;
272 static void
273 remove_output ()
275 if (output_filename != NULL)
277 if (output_bfd != NULL && output_bfd->iostream != NULL)
278 fclose ((FILE *) (output_bfd->iostream));
279 if (output_file != NULL)
280 fclose (output_file);
281 unlink (output_filename);
285 /* The option parsing should be in its own function.
286 It will be when I have getopt working. */
289 main (argc, argv)
290 int argc;
291 char **argv;
293 char *arg_ptr;
294 char c;
295 enum
297 none = 0, delete, replace, print_table,
298 print_files, extract, move, quick_append
299 } operation = none;
300 int arg_index;
301 char **files;
302 char *inarch_filename;
303 int show_version;
305 program_name = argv[0];
306 xmalloc_set_program_name (program_name);
308 if (is_ranlib < 0)
310 char *temp;
312 temp = strrchr (program_name, '/');
313 if (temp == NULL)
314 temp = program_name;
315 else
316 ++temp;
317 if (strlen (temp) >= 6
318 && strcmp (temp + strlen (temp) - 6, "ranlib") == 0)
319 is_ranlib = 1;
320 else
321 is_ranlib = 0;
324 if (argc > 1 && argv[1][0] == '-')
326 if (strcmp (argv[1], "--help") == 0)
327 usage (1);
328 else if (strcmp (argv[1], "--version") == 0)
330 if (is_ranlib)
331 print_version ("ranlib");
332 else
333 print_version ("ar");
337 START_PROGRESS (program_name, 0);
339 bfd_init ();
340 show_version = 0;
342 xatexit (remove_output);
344 if (is_ranlib)
346 boolean touch = false;
348 if (argc < 2 || strcmp (argv[1], "--help") == 0)
349 usage ();
350 if (strcmp (argv[1], "-V") == 0
351 || strcmp (argv[1], "-v") == 0
352 || strncmp (argv[1], "--v", 3) == 0)
353 print_version ("ranlib");
354 arg_index = 1;
355 if (strcmp (argv[1], "-t") == 0)
357 ++arg_index;
358 touch = true;
360 while (arg_index < argc)
362 if (! touch)
363 ranlib_only (argv[arg_index]);
364 else
365 ranlib_touch (argv[arg_index]);
366 ++arg_index;
368 xexit (0);
371 if (argc == 2 && strcmp (argv[1], "-M") == 0)
373 mri_emul ();
374 xexit (0);
377 if (argc < 2)
378 usage ();
380 arg_ptr = argv[1];
382 if (*arg_ptr == '-')
383 ++arg_ptr; /* compatibility */
385 while ((c = *arg_ptr++) != '\0')
387 switch (c)
389 case 'd':
390 case 'm':
391 case 'p':
392 case 'q':
393 case 'r':
394 case 't':
395 case 'x':
396 if (operation != none)
397 fatal ("two different operation options specified");
398 switch (c)
400 case 'd':
401 operation = delete;
402 operation_alters_arch = true;
403 break;
404 case 'm':
405 operation = move;
406 operation_alters_arch = true;
407 break;
408 case 'p':
409 operation = print_files;
410 break;
411 case 'q':
412 operation = quick_append;
413 operation_alters_arch = true;
414 break;
415 case 'r':
416 operation = replace;
417 operation_alters_arch = true;
418 break;
419 case 't':
420 operation = print_table;
421 break;
422 case 'x':
423 operation = extract;
424 break;
426 case 'l':
427 break;
428 case 'c':
429 silent_create = 1;
430 break;
431 case 'o':
432 preserve_dates = 1;
433 break;
434 case 'V':
435 show_version = true;
436 break;
437 case 's':
438 write_armap = 1;
439 break;
440 case 'u':
441 newer_only = 1;
442 break;
443 case 'v':
444 verbose = 1;
445 break;
446 case 'a':
447 postype = pos_after;
448 break;
449 case 'b':
450 postype = pos_before;
451 break;
452 case 'i':
453 postype = pos_before;
454 break;
455 case 'M':
456 mri_mode = 1;
457 break;
458 case 'f':
459 ar_truncate = true;
460 break;
461 default:
462 fprintf (stderr, "%s: illegal option -- %c\n", program_name, c);
463 usage ();
467 if (show_version)
468 print_version ("ar");
470 if (argc < 3)
471 usage ();
473 if (mri_mode)
475 mri_emul ();
477 else
479 bfd *arch;
481 /* We can't write an armap when using ar q, so just do ar r
482 instead. */
483 if (operation == quick_append && write_armap)
484 operation = replace;
486 if ((operation == none || operation == print_table)
487 && write_armap == 1)
489 ranlib_only (argv[2]);
490 xexit (0);
493 if (operation == none)
494 fatal ("no operation specified");
496 if (newer_only && operation != replace)
497 fatal ("`u' is only meaningful with the `r' option.");
499 arg_index = 2;
501 if (postype != pos_default)
502 posname = argv[arg_index++];
504 inarch_filename = argv[arg_index++];
506 files = arg_index < argc ? argv + arg_index : NULL;
508 #if 0
509 /* We don't use do_quick_append any more. Too many systems
510 expect ar to always rebuild the symbol table even when q is
511 used. */
513 /* We can't do a quick append if we need to construct an
514 extended name table, because do_quick_append won't be able to
515 rebuild the name table. Unfortunately, at this point we
516 don't actually know the maximum name length permitted by this
517 object file format. So, we guess. FIXME. */
518 if (operation == quick_append && ! ar_truncate)
520 char **chk;
522 for (chk = files; chk != NULL && *chk != '\0'; chk++)
524 if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
526 operation = replace;
527 break;
532 if (operation == quick_append)
534 /* Note that quick appending to a non-existent archive creates it,
535 even if there are no files to append. */
536 do_quick_append (inarch_filename, files);
537 xexit (0);
539 #endif
541 arch = open_inarch (inarch_filename,
542 files == NULL ? (char *) NULL : files[0]);
544 switch (operation)
546 case print_table:
547 map_over_members (arch, print_descr, files, argc - 3);
548 break;
550 case print_files:
551 map_over_members (arch, print_contents, files, argc - 3);
552 break;
554 case extract:
555 map_over_members (arch, extract_file, files, argc - 3);
556 break;
558 case delete:
559 if (files != NULL)
560 delete_members (arch, files);
561 break;
563 case move:
564 if (files != NULL)
565 move_members (arch, files);
566 break;
568 case replace:
569 case quick_append:
570 if (files != NULL || write_armap > 0)
571 replace_members (arch, files, operation == quick_append);
572 break;
574 /* Shouldn't happen! */
575 default:
576 fprintf (stderr, "%s: internal error -- this option not implemented\n",
577 program_name);
578 xexit (1);
582 END_PROGRESS (program_name);
584 xexit (0);
585 return 0;
588 bfd *
589 open_inarch (archive_filename, file)
590 const char *archive_filename;
591 const char *file;
593 const char *target;
594 bfd **last_one;
595 bfd *next_one;
596 struct stat sbuf;
597 bfd *arch;
598 char **matching;
600 bfd_set_error (bfd_error_no_error);
602 target = NULL;
604 if (stat (archive_filename, &sbuf) != 0)
606 bfd *obj;
608 #ifndef __GO32__
610 /* KLUDGE ALERT! Temporary fix until I figger why
611 * stat() is wrong ... think it's buried in GO32's IDT
612 * - Jax
614 if (errno != ENOENT)
615 bfd_fatal (archive_filename);
616 #endif
618 if (!operation_alters_arch)
620 fprintf (stderr, "%s: ", program_name);
621 perror (archive_filename);
622 maybequit ();
623 return NULL;
626 /* Try to figure out the target to use for the archive from the
627 first object on the list. */
628 obj = bfd_openr (file, NULL);
629 if (obj != NULL)
631 if (bfd_check_format (obj, bfd_object))
632 target = bfd_get_target (obj);
633 (void) bfd_close (obj);
636 /* Create an empty archive. */
637 arch = bfd_openw (archive_filename, target);
638 if (arch == NULL
639 || ! bfd_set_format (arch, bfd_archive)
640 || ! bfd_close (arch))
641 bfd_fatal (archive_filename);
644 arch = bfd_openr (archive_filename, target);
645 if (arch == NULL)
647 bloser:
648 bfd_fatal (archive_filename);
651 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
653 bfd_nonfatal (archive_filename);
654 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
656 list_matching_formats (matching);
657 free (matching);
659 xexit (1);
662 last_one = &(arch->next);
663 /* Read all the contents right away, regardless. */
664 for (next_one = bfd_openr_next_archived_file (arch, NULL);
665 next_one;
666 next_one = bfd_openr_next_archived_file (arch, next_one))
668 PROGRESS (1);
669 *last_one = next_one;
670 last_one = &next_one->next;
672 *last_one = (bfd *) NULL;
673 if (bfd_get_error () != bfd_error_no_more_archived_files)
674 goto bloser;
675 return arch;
678 static void
679 print_contents (abfd)
680 bfd *abfd;
682 int ncopied = 0;
683 char *cbuf = xmalloc (BUFSIZE);
684 struct stat buf;
685 long size;
686 if (bfd_stat_arch_elt (abfd, &buf) != 0)
687 fatal ("internal stat error on %s", bfd_get_filename (abfd));
689 if (verbose)
690 printf ("\n<member %s>\n\n", bfd_get_filename (abfd));
692 bfd_seek (abfd, 0, SEEK_SET);
694 size = buf.st_size;
695 while (ncopied < size)
698 int nread;
699 int tocopy = size - ncopied;
700 if (tocopy > BUFSIZE)
701 tocopy = BUFSIZE;
703 nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke
704 abstraction! */
705 if (nread != tocopy)
706 fatal ("%s is not a valid archive",
707 bfd_get_filename (bfd_my_archive (abfd)));
708 fwrite (cbuf, 1, nread, stdout);
709 ncopied += tocopy;
711 free (cbuf);
714 /* Extract a member of the archive into its own file.
716 We defer opening the new file until after we have read a BUFSIZ chunk of the
717 old one, since we know we have just read the archive header for the old
718 one. Since most members are shorter than BUFSIZ, this means we will read
719 the old header, read the old data, write a new inode for the new file, and
720 write the new data, and be done. This 'optimization' is what comes from
721 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
722 Gilmore */
724 void
725 extract_file (abfd)
726 bfd *abfd;
728 FILE *ostream;
729 char *cbuf = xmalloc (BUFSIZE);
730 int nread, tocopy;
731 int ncopied = 0;
732 long size;
733 struct stat buf;
734 if (bfd_stat_arch_elt (abfd, &buf) != 0)
735 fatal ("internal stat error on %s", bfd_get_filename (abfd));
736 size = buf.st_size;
738 if (verbose)
739 printf ("x - %s\n", bfd_get_filename (abfd));
741 bfd_seek (abfd, 0, SEEK_SET);
743 ostream = 0;
744 if (size == 0)
746 /* Seems like an abstraction violation, eh? Well it's OK! */
747 output_filename = bfd_get_filename (abfd);
749 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
750 if (!ostream)
752 perror (bfd_get_filename (abfd));
753 xexit (1);
756 output_file = ostream;
758 else
759 while (ncopied < size)
761 tocopy = size - ncopied;
762 if (tocopy > BUFSIZE)
763 tocopy = BUFSIZE;
765 nread = bfd_read (cbuf, 1, tocopy, abfd);
766 if (nread != tocopy)
767 fatal ("%s is not a valid archive",
768 bfd_get_filename (bfd_my_archive (abfd)));
770 /* See comment above; this saves disk arm motion */
771 if (!ostream)
773 /* Seems like an abstraction violation, eh? Well it's OK! */
774 output_filename = bfd_get_filename (abfd);
776 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
777 if (!ostream)
779 perror (bfd_get_filename (abfd));
780 xexit (1);
783 output_file = ostream;
785 fwrite (cbuf, 1, nread, ostream);
786 ncopied += tocopy;
789 fclose (ostream);
791 output_file = NULL;
792 output_filename = NULL;
794 chmod (bfd_get_filename (abfd), buf.st_mode);
796 if (preserve_dates)
798 #ifdef HAVE_GOOD_UTIME_H
799 struct utimbuf tb;
800 tb.actime = buf.st_mtime;
801 tb.modtime = buf.st_mtime;
802 utime (bfd_get_filename (abfd), &tb); /* FIXME check result */
803 #else /* ! HAVE_GOOD_UTIME_H */
804 #ifndef HAVE_UTIMES
805 long tb[2];
806 tb[0] = buf.st_mtime;
807 tb[1] = buf.st_mtime;
808 utime (bfd_get_filename (abfd), tb); /* FIXME check result */
809 #else /* HAVE_UTIMES */
810 struct timeval tv[2];
811 tv[0].tv_sec = buf.st_mtime;
812 tv[0].tv_usec = 0;
813 tv[1].tv_sec = buf.st_mtime;
814 tv[1].tv_usec = 0;
815 utimes (bfd_get_filename (abfd), tv); /* FIXME check result */
816 #endif /* HAVE_UTIMES */
817 #endif /* ! HAVE_GOOD_UTIME_H */
819 free (cbuf);
822 #if 0
824 /* We don't use this anymore. Too many systems expect ar to rebuild
825 the symbol table even when q is used. */
827 /* Just do it quickly; don't worry about dups, armap, or anything like that */
829 static void
830 do_quick_append (archive_filename, files_to_append)
831 const char *archive_filename;
832 char **files_to_append;
834 FILE *ofile, *ifile;
835 char *buf = xmalloc (BUFSIZE);
836 long tocopy, thistime;
837 bfd *temp;
838 struct stat sbuf;
839 boolean newfile = false;
840 bfd_set_error (bfd_error_no_error);
842 if (stat (archive_filename, &sbuf) != 0)
845 #ifndef __GO32__
847 /* KLUDGE ALERT! Temporary fix until I figger why
848 * stat() is wrong ... think it's buried in GO32's IDT
849 * - Jax
852 if (errno != ENOENT)
853 bfd_fatal (archive_filename);
854 #endif
856 newfile = true;
859 ofile = fopen (archive_filename, FOPEN_AUB);
860 if (ofile == NULL)
862 perror (program_name);
863 xexit (1);
866 temp = bfd_openr (archive_filename, NULL);
867 if (temp == NULL)
869 bfd_fatal (archive_filename);
871 if (newfile == false)
873 if (bfd_check_format (temp, bfd_archive) != true)
874 fatal ("%s is not an archive", archive_filename);
876 else
878 fwrite (ARMAG, 1, SARMAG, ofile);
879 if (!silent_create)
880 fprintf (stderr, "%s: creating %s\n",
881 program_name, archive_filename);
884 if (ar_truncate)
885 temp->flags |= BFD_TRADITIONAL_FORMAT;
887 /* assume it's an achive, go straight to the end, sans $200 */
888 fseek (ofile, 0, 2);
890 for (; files_to_append && *files_to_append; ++files_to_append)
892 struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
893 if (hdr == NULL)
895 bfd_fatal (*files_to_append);
898 BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
900 ifile = fopen (*files_to_append, FOPEN_RB);
901 if (ifile == NULL)
903 bfd_nonfatal (*files_to_append);
906 if (stat (*files_to_append, &sbuf) != 0)
908 bfd_nonfatal (*files_to_append);
911 tocopy = sbuf.st_size;
913 /* XXX should do error-checking! */
914 fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
916 while (tocopy > 0)
918 thistime = tocopy;
919 if (thistime > BUFSIZE)
920 thistime = BUFSIZE;
921 fread (buf, 1, thistime, ifile);
922 fwrite (buf, 1, thistime, ofile);
923 tocopy -= thistime;
925 fclose (ifile);
926 if ((sbuf.st_size % 2) == 1)
927 putc ('\012', ofile);
929 fclose (ofile);
930 bfd_close (temp);
931 free (buf);
934 #endif /* 0 */
936 static void
937 write_archive (iarch)
938 bfd *iarch;
940 bfd *obfd;
941 char *old_name, *new_name;
942 bfd *contents_head = iarch->next;
944 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
945 strcpy (old_name, bfd_get_filename (iarch));
946 new_name = make_tempname (old_name);
948 output_filename = new_name;
950 obfd = bfd_openw (new_name, bfd_get_target (iarch));
952 if (obfd == NULL)
953 bfd_fatal (old_name);
955 output_bfd = obfd;
957 bfd_set_format (obfd, bfd_archive);
959 /* Request writing the archive symbol table unless we've
960 been explicitly requested not to. */
961 obfd->has_armap = write_armap >= 0;
963 if (ar_truncate)
965 /* This should really use bfd_set_file_flags, but that rejects
966 archives. */
967 obfd->flags |= BFD_TRADITIONAL_FORMAT;
970 if (bfd_set_archive_head (obfd, contents_head) != true)
971 bfd_fatal (old_name);
973 if (!bfd_close (obfd))
974 bfd_fatal (old_name);
976 output_bfd = NULL;
977 output_filename = NULL;
979 /* We don't care if this fails; we might be creating the archive. */
980 bfd_close (iarch);
981 unlink (old_name);
983 if (rename (new_name, old_name) != 0)
984 bfd_fatal (old_name);
987 /* Return a pointer to the pointer to the entry which should be rplacd'd
988 into when altering. DEFAULT_POS should be how to interpret pos_default,
989 and should be a pos value. */
991 bfd **
992 get_pos_bfd (contents, default_pos)
993 bfd **contents;
994 enum pos default_pos;
996 bfd **after_bfd = contents;
997 enum pos realpos = (postype == pos_default ? default_pos : postype);
999 if (realpos == pos_end)
1001 while (*after_bfd)
1002 after_bfd = &((*after_bfd)->next);
1004 else
1006 for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1007 if (!strcmp ((*after_bfd)->filename, posname))
1009 if (realpos == pos_after)
1010 after_bfd = &(*after_bfd)->next;
1011 break;
1014 return after_bfd;
1017 static void
1018 delete_members (arch, files_to_delete)
1019 bfd *arch;
1020 char **files_to_delete;
1022 bfd **current_ptr_ptr;
1023 boolean found;
1024 boolean something_changed = false;
1025 for (; *files_to_delete != NULL; ++files_to_delete)
1027 /* In a.out systems, the armap is optional. It's also called
1028 __.SYMDEF. So if the user asked to delete it, we should remember
1029 that fact. This isn't quite right for COFF systems (where
1030 __.SYMDEF might be regular member), but it's very unlikely
1031 to be a problem. FIXME */
1033 if (!strcmp (*files_to_delete, "__.SYMDEF"))
1035 arch->has_armap = false;
1036 write_armap = -1;
1037 continue;
1040 found = false;
1041 current_ptr_ptr = &(arch->next);
1042 while (*current_ptr_ptr)
1044 if (strcmp (*files_to_delete, (*current_ptr_ptr)->filename) == 0)
1046 found = true;
1047 something_changed = true;
1048 if (verbose)
1049 printf ("d - %s\n",
1050 *files_to_delete);
1051 *current_ptr_ptr = ((*current_ptr_ptr)->next);
1052 goto next_file;
1054 else
1056 current_ptr_ptr = &((*current_ptr_ptr)->next);
1060 if (verbose && found == false)
1062 printf ("No member named `%s'\n", *files_to_delete);
1064 next_file:
1068 if (something_changed == true)
1070 write_archive (arch);
1075 /* Reposition existing members within an archive */
1077 static void
1078 move_members (arch, files_to_move)
1079 bfd *arch;
1080 char **files_to_move;
1082 bfd **after_bfd; /* New entries go after this one */
1083 bfd **current_ptr_ptr; /* cdr pointer into contents */
1085 for (; *files_to_move; ++files_to_move)
1087 current_ptr_ptr = &(arch->next);
1088 while (*current_ptr_ptr)
1090 bfd *current_ptr = *current_ptr_ptr;
1091 if (strcmp (normalize (*files_to_move, arch),
1092 current_ptr->filename) == 0)
1094 /* Move this file to the end of the list - first cut from
1095 where it is. */
1096 bfd *link;
1097 *current_ptr_ptr = current_ptr->next;
1099 /* Now glue to end */
1100 after_bfd = get_pos_bfd (&arch->next, pos_end);
1101 link = *after_bfd;
1102 *after_bfd = current_ptr;
1103 current_ptr->next = link;
1105 if (verbose)
1106 printf ("m - %s\n", *files_to_move);
1108 goto next_file;
1111 current_ptr_ptr = &((*current_ptr_ptr)->next);
1113 fprintf (stderr, "%s: no entry %s in archive %s!\n",
1114 program_name, *files_to_move, arch->filename);
1115 xexit (1);
1116 next_file:;
1119 write_archive (arch);
1122 /* Ought to default to replacing in place, but this is existing practice! */
1124 static void
1125 replace_members (arch, files_to_move, quick)
1126 bfd *arch;
1127 char **files_to_move;
1128 boolean quick;
1130 boolean changed = false;
1131 bfd **after_bfd; /* New entries go after this one */
1132 bfd *current;
1133 bfd **current_ptr;
1134 bfd *temp;
1136 while (files_to_move && *files_to_move)
1138 if (! quick)
1140 current_ptr = &arch->next;
1141 while (*current_ptr)
1143 current = *current_ptr;
1145 /* For compatibility with existing ar programs, we
1146 permit the same file to be added multiple times. */
1147 if (strcmp (normalize (*files_to_move, arch),
1148 normalize (current->filename, arch)) == 0
1149 && current->arelt_data != NULL)
1151 if (newer_only)
1153 struct stat fsbuf, asbuf;
1155 if (stat (*files_to_move, &fsbuf) != 0)
1157 if (errno != ENOENT)
1158 bfd_fatal (*files_to_move);
1159 goto next_file;
1161 if (bfd_stat_arch_elt (current, &asbuf) != 0)
1162 fatal ("internal stat error on %s", current->filename);
1164 if (fsbuf.st_mtime <= asbuf.st_mtime)
1165 goto next_file;
1168 /* snip out this entry from the chain */
1169 *current_ptr = current->next;
1171 after_bfd = get_pos_bfd (&arch->next, pos_end);
1172 temp = *after_bfd;
1173 *after_bfd = bfd_openr (*files_to_move, NULL);
1174 if (*after_bfd == (bfd *) NULL)
1176 bfd_fatal (*files_to_move);
1178 (*after_bfd)->next = temp;
1180 if (verbose)
1182 printf ("r - %s\n", *files_to_move);
1185 changed = true;
1187 goto next_file;
1189 current_ptr = &(current->next);
1193 /* Add to the end of the archive. */
1195 after_bfd = get_pos_bfd (&arch->next, pos_end);
1196 temp = *after_bfd;
1197 *after_bfd = bfd_openr (*files_to_move, NULL);
1198 if (*after_bfd == (bfd *) NULL)
1200 bfd_fatal (*files_to_move);
1202 if (verbose)
1204 printf ("a - %s\n", *files_to_move);
1207 (*after_bfd)->next = temp;
1209 changed = true;
1211 next_file:;
1213 files_to_move++;
1216 if (changed)
1217 write_archive (arch);
1220 static void
1221 ranlib_only (archname)
1222 const char *archname;
1224 bfd *arch;
1226 write_armap = 1;
1227 arch = open_inarch (archname, (char *) NULL);
1228 if (arch == NULL)
1229 xexit (1);
1230 write_archive (arch);
1233 /* Update the timestamp of the symbol map of an archive. */
1235 static void
1236 ranlib_touch (archname)
1237 const char *archname;
1239 #ifdef __GO32__
1240 /* I don't think updating works on go32. */
1241 ranlib_only (archname);
1242 #else
1243 int f;
1244 bfd *arch;
1245 char **matching;
1247 f = open (archname, O_RDWR, 0);
1248 if (f < 0)
1250 bfd_set_error (bfd_error_system_call);
1251 bfd_fatal (archname);
1254 arch = bfd_fdopenr (archname, (const char *) NULL, f);
1255 if (arch == NULL)
1256 bfd_fatal (archname);
1257 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1259 bfd_nonfatal (archname);
1260 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1262 list_matching_formats (matching);
1263 free (matching);
1265 xexit (1);
1268 if (! bfd_has_map (arch))
1269 fatal ("%s: no archive map to update", archname);
1271 bfd_update_armap_timestamp (arch);
1273 if (! bfd_close (arch))
1274 bfd_fatal (archname);
1275 #endif
1278 /* Things which are interesting to map over all or some of the files: */
1280 static void
1281 print_descr (abfd)
1282 bfd *abfd;
1284 print_arelt_descr (stdout, abfd, verbose);