2002-09-20 Nathanael Nerode <neroden@gcc.gnu.org>
[binutils.git] / binutils / ar.c
blobea1b456d9e56b15e3d8979a70e75a6096fd0f394
1 /* ar.c - Archive modify and extract.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002
4 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 Bugs: should use getopt the way tar does (complete w/optional -) and
24 should have long options too. GNU ar used to check file against filesystem
25 in quick_update and replace operations (would check mtime). Doesn't warn
26 when name truncated. No way to specify pos_end. Error messages should be
27 more consistant. */
29 #include "bfd.h"
30 #include "libiberty.h"
31 #include "progress.h"
32 #include "bucomm.h"
33 #include "aout/ar.h"
34 #include "libbfd.h"
35 #include "arsup.h"
36 #include "filenames.h"
37 #include "binemul.h"
38 #include <sys/stat.h>
40 #ifdef __GO32___
41 #define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
42 #else
43 #define EXT_NAME_LEN 6 /* ditto for *NIX */
44 #endif
46 /* We need to open files in binary modes on system where that makes a
47 difference. */
48 #ifndef O_BINARY
49 #define O_BINARY 0
50 #endif
52 #define BUFSIZE 8192
54 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
56 struct ar_hdr *
57 bfd_special_undocumented_glue PARAMS ((bfd * abfd, const char *filename));
59 /* Static declarations */
61 static void
62 mri_emul PARAMS ((void));
64 static const char *
65 normalize PARAMS ((const char *, bfd *));
67 static void
68 remove_output PARAMS ((void));
70 static void
71 map_over_members PARAMS ((bfd *, void (*)(bfd *), char **, int));
73 static void
74 print_contents PARAMS ((bfd * member));
76 static void
77 delete_members PARAMS ((bfd *, char **files_to_delete));
79 #if 0
80 static void
81 do_quick_append PARAMS ((const char *archive_filename,
82 char **files_to_append));
83 #endif
85 static void
86 move_members PARAMS ((bfd *, char **files_to_move));
88 static void
89 replace_members PARAMS ((bfd *, char **files_to_replace, boolean quick));
91 static void
92 print_descr PARAMS ((bfd * abfd));
94 static void
95 write_archive PARAMS ((bfd *));
97 static void
98 ranlib_only PARAMS ((const char *archname));
100 static void
101 ranlib_touch PARAMS ((const char *archname));
103 static void
104 usage PARAMS ((int));
106 /** Globals and flags */
108 int mri_mode;
110 /* This flag distinguishes between ar and ranlib:
111 1 means this is 'ranlib'; 0 means this is 'ar'.
112 -1 means if we should use argv[0] to decide. */
113 extern int is_ranlib;
115 /* Nonzero means don't warn about creating the archive file if necessary. */
116 int silent_create = 0;
118 /* Nonzero means describe each action performed. */
119 int verbose = 0;
121 /* Nonzero means preserve dates of members when extracting them. */
122 int preserve_dates = 0;
124 /* Nonzero means don't replace existing members whose dates are more recent
125 than the corresponding files. */
126 int newer_only = 0;
128 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
129 member). -1 means we've been explicitly asked to not write a symbol table;
130 +1 means we've been explictly asked to write it;
131 0 is the default.
132 Traditionally, the default in BSD has been to not write the table.
133 However, for POSIX.2 compliance the default is now to write a symbol table
134 if any of the members are object files. */
135 int write_armap = 0;
137 /* Nonzero means it's the name of an existing member; position new or moved
138 files with respect to this one. */
139 char *posname = NULL;
141 /* Sez how to use `posname': pos_before means position before that member.
142 pos_after means position after that member. pos_end means always at end.
143 pos_default means default appropriately. For the latter two, `posname'
144 should also be zero. */
145 enum pos
147 pos_default, pos_before, pos_after, pos_end
148 } postype = pos_default;
150 static bfd **
151 get_pos_bfd PARAMS ((bfd **, enum pos, const char *));
153 /* For extract/delete only. If COUNTED_NAME_MODE is true, we only
154 extract the COUNTED_NAME_COUNTER instance of that name. */
155 static boolean counted_name_mode = 0;
156 static int counted_name_counter = 0;
158 /* Whether to truncate names of files stored in the archive. */
159 static boolean ar_truncate = false;
161 /* Whether to use a full file name match when searching an archive.
162 This is convenient for archives created by the Microsoft lib
163 program. */
164 static boolean full_pathname = false;
166 int interactive = 0;
168 static void
169 mri_emul ()
171 interactive = isatty (fileno (stdin));
172 yyparse ();
175 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
176 COUNT is the length of the FILES chain; FUNCTION is called on each entry
177 whose name matches one in FILES. */
179 static void
180 map_over_members (arch, function, files, count)
181 bfd *arch;
182 void (*function) PARAMS ((bfd *));
183 char **files;
184 int count;
186 bfd *head;
187 int match_count;
189 if (count == 0)
191 for (head = arch->next; head; head = head->next)
193 PROGRESS (1);
194 function (head);
196 return;
199 /* This may appear to be a baroque way of accomplishing what we want.
200 However we have to iterate over the filenames in order to notice where
201 a filename is requested but does not exist in the archive. Ditto
202 mapping over each file each time -- we want to hack multiple
203 references. */
205 for (; count > 0; files++, count--)
207 boolean found = false;
209 match_count = 0;
210 for (head = arch->next; head; head = head->next)
212 PROGRESS (1);
213 if (head->filename == NULL)
215 /* Some archive formats don't get the filenames filled in
216 until the elements are opened. */
217 struct stat buf;
218 bfd_stat_arch_elt (head, &buf);
220 if ((head->filename != NULL) &&
221 (!FILENAME_CMP (normalize (*files, arch), head->filename)))
223 ++match_count;
224 if (counted_name_mode
225 && match_count != counted_name_counter)
227 /* Counting, and didn't match on count; go on to the
228 next one. */
229 continue;
232 found = true;
233 function (head);
236 if (!found)
237 /* xgettext:c-format */
238 fprintf (stderr, _("no entry %s in archive\n"), *files);
242 boolean operation_alters_arch = false;
244 static void
245 usage (help)
246 int help;
248 FILE *s;
250 s = help ? stdout : stderr;
252 if (! is_ranlib)
254 /* xgettext:c-format */
255 fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
256 program_name);
257 /* xgettext:c-format */
258 fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
259 fprintf (s, _(" commands:\n"));
260 fprintf (s, _(" d - delete file(s) from the archive\n"));
261 fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
262 fprintf (s, _(" p - print file(s) found in the archive\n"));
263 fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
264 fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
265 fprintf (s, _(" t - display contents of archive\n"));
266 fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
267 fprintf (s, _(" command specific modifiers:\n"));
268 fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
269 fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
270 fprintf (s, _(" [N] - use instance [count] of name\n"));
271 fprintf (s, _(" [f] - truncate inserted file names\n"));
272 fprintf (s, _(" [P] - use full path names when matching\n"));
273 fprintf (s, _(" [o] - preserve original dates\n"));
274 fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
275 fprintf (s, _(" generic modifiers:\n"));
276 fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
277 fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
278 fprintf (s, _(" [S] - do not build a symbol table\n"));
279 fprintf (s, _(" [v] - be verbose\n"));
280 fprintf (s, _(" [V] - display the version number\n"));
282 ar_emul_usage (s);
284 else
286 /* xgettext:c-format */
287 fprintf (s, _("Usage: %s [options] archive\n"), program_name);
288 fprintf (s, _(" Generate an index to speed access to archives\n"));
289 fprintf (s, _(" The options are:\n\
290 -h --help Print this help message\n\
291 -V --version Print version information\n"));
294 list_supported_targets (program_name, stderr);
296 if (help)
297 fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
299 xexit (help ? 0 : 1);
302 /* Normalize a file name specified on the command line into a file
303 name which we will use in an archive. */
305 static const char *
306 normalize (file, abfd)
307 const char *file;
308 bfd *abfd;
310 const char *filename;
312 if (full_pathname)
313 return file;
315 filename = strrchr (file, '/');
316 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
318 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
319 char *bslash = strrchr (file, '\\');
320 if (filename == NULL || (bslash != NULL && bslash > filename))
321 filename = bslash;
322 if (filename == NULL && file[0] != '\0' && file[1] == ':')
323 filename = file + 1;
325 #endif
326 if (filename != (char *) NULL)
327 filename++;
328 else
329 filename = file;
331 if (ar_truncate
332 && abfd != NULL
333 && strlen (filename) > abfd->xvec->ar_max_namelen)
335 char *s;
337 /* Space leak. */
338 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
339 memcpy (s, filename, abfd->xvec->ar_max_namelen);
340 s[abfd->xvec->ar_max_namelen] = '\0';
341 filename = s;
344 return filename;
347 /* Remove any output file. This is only called via xatexit. */
349 static const char *output_filename = NULL;
350 static FILE *output_file = NULL;
351 static bfd *output_bfd = NULL;
353 static void
354 remove_output ()
356 if (output_filename != NULL)
358 if (output_bfd != NULL && output_bfd->iostream != NULL)
359 fclose ((FILE *) (output_bfd->iostream));
360 if (output_file != NULL)
361 fclose (output_file);
362 unlink (output_filename);
366 /* The option parsing should be in its own function.
367 It will be when I have getopt working. */
369 int main PARAMS ((int, char **));
372 main (argc, argv)
373 int argc;
374 char **argv;
376 char *arg_ptr;
377 char c;
378 enum
380 none = 0, delete, replace, print_table,
381 print_files, extract, move, quick_append
382 } operation = none;
383 int arg_index;
384 char **files;
385 int file_count;
386 char *inarch_filename;
387 int show_version;
388 int i;
390 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
391 setlocale (LC_MESSAGES, "");
392 #endif
393 #if defined (HAVE_SETLOCALE)
394 setlocale (LC_CTYPE, "");
395 #endif
396 bindtextdomain (PACKAGE, LOCALEDIR);
397 textdomain (PACKAGE);
399 program_name = argv[0];
400 xmalloc_set_program_name (program_name);
402 if (is_ranlib < 0)
404 char *temp;
406 temp = strrchr (program_name, '/');
407 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
409 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
410 char *bslash = strrchr (program_name, '\\');
411 if (temp == NULL || (bslash != NULL && bslash > temp))
412 temp = bslash;
413 if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
414 temp = program_name + 1;
416 #endif
417 if (temp == NULL)
418 temp = program_name;
419 else
420 ++temp;
421 if (strlen (temp) >= 6
422 && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
423 is_ranlib = 1;
424 else
425 is_ranlib = 0;
428 if (argc > 1 && argv[1][0] == '-')
430 if (strcmp (argv[1], "--help") == 0)
431 usage (1);
432 else if (strcmp (argv[1], "--version") == 0)
434 if (is_ranlib)
435 print_version ("ranlib");
436 else
437 print_version ("ar");
441 START_PROGRESS (program_name, 0);
443 bfd_init ();
444 set_default_bfd_target ();
446 show_version = 0;
448 xatexit (remove_output);
450 for (i = 1; i < argc; i++)
451 if (! ar_emul_parse_arg (argv[i]))
452 break;
453 argv += (i - 1);
454 argc -= (i - 1);
456 if (is_ranlib)
458 boolean touch = false;
460 if (argc < 2
461 || strcmp (argv[1], "--help") == 0
462 || strcmp (argv[1], "-h") == 0
463 || strcmp (argv[1], "-H") == 0)
464 usage (0);
465 if (strcmp (argv[1], "-V") == 0
466 || strcmp (argv[1], "-v") == 0
467 || strncmp (argv[1], "--v", 3) == 0)
468 print_version ("ranlib");
469 arg_index = 1;
470 if (strcmp (argv[1], "-t") == 0)
472 ++arg_index;
473 touch = true;
475 while (arg_index < argc)
477 if (! touch)
478 ranlib_only (argv[arg_index]);
479 else
480 ranlib_touch (argv[arg_index]);
481 ++arg_index;
483 xexit (0);
486 if (argc == 2 && strcmp (argv[1], "-M") == 0)
488 mri_emul ();
489 xexit (0);
492 if (argc < 2)
493 usage (0);
495 arg_ptr = argv[1];
497 if (*arg_ptr == '-')
498 ++arg_ptr; /* compatibility */
500 while ((c = *arg_ptr++) != '\0')
502 switch (c)
504 case 'd':
505 case 'm':
506 case 'p':
507 case 'q':
508 case 'r':
509 case 't':
510 case 'x':
511 if (operation != none)
512 fatal (_("two different operation options specified"));
513 switch (c)
515 case 'd':
516 operation = delete;
517 operation_alters_arch = true;
518 break;
519 case 'm':
520 operation = move;
521 operation_alters_arch = true;
522 break;
523 case 'p':
524 operation = print_files;
525 break;
526 case 'q':
527 operation = quick_append;
528 operation_alters_arch = true;
529 break;
530 case 'r':
531 operation = replace;
532 operation_alters_arch = true;
533 break;
534 case 't':
535 operation = print_table;
536 break;
537 case 'x':
538 operation = extract;
539 break;
541 case 'l':
542 break;
543 case 'c':
544 silent_create = 1;
545 break;
546 case 'o':
547 preserve_dates = 1;
548 break;
549 case 'V':
550 show_version = true;
551 break;
552 case 's':
553 write_armap = 1;
554 break;
555 case 'S':
556 write_armap = -1;
557 break;
558 case 'u':
559 newer_only = 1;
560 break;
561 case 'v':
562 verbose = 1;
563 break;
564 case 'a':
565 postype = pos_after;
566 break;
567 case 'b':
568 postype = pos_before;
569 break;
570 case 'i':
571 postype = pos_before;
572 break;
573 case 'M':
574 mri_mode = 1;
575 break;
576 case 'N':
577 counted_name_mode = true;
578 break;
579 case 'f':
580 ar_truncate = true;
581 break;
582 case 'P':
583 full_pathname = true;
584 break;
585 default:
586 /* xgettext:c-format */
587 non_fatal (_("illegal option -- %c"), c);
588 usage (0);
592 if (show_version)
593 print_version ("ar");
595 if (argc < 3)
596 usage (0);
598 if (mri_mode)
600 mri_emul ();
602 else
604 bfd *arch;
606 /* We can't write an armap when using ar q, so just do ar r
607 instead. */
608 if (operation == quick_append && write_armap)
609 operation = replace;
611 if ((operation == none || operation == print_table)
612 && write_armap == 1)
614 ranlib_only (argv[2]);
615 xexit (0);
618 if (operation == none)
619 fatal (_("no operation specified"));
621 if (newer_only && operation != replace)
622 fatal (_("`u' is only meaningful with the `r' option."));
624 arg_index = 2;
626 if (postype != pos_default)
627 posname = argv[arg_index++];
629 if (counted_name_mode)
631 if (operation != extract && operation != delete)
632 fatal (_("`N' is only meaningful with the `x' and `d' options."));
633 counted_name_counter = atoi (argv[arg_index++]);
634 if (counted_name_counter <= 0)
635 fatal (_("Value for `N' must be positive."));
638 inarch_filename = argv[arg_index++];
640 files = arg_index < argc ? argv + arg_index : NULL;
641 file_count = argc - arg_index;
643 #if 0
644 /* We don't use do_quick_append any more. Too many systems
645 expect ar to always rebuild the symbol table even when q is
646 used. */
648 /* We can't do a quick append if we need to construct an
649 extended name table, because do_quick_append won't be able to
650 rebuild the name table. Unfortunately, at this point we
651 don't actually know the maximum name length permitted by this
652 object file format. So, we guess. FIXME. */
653 if (operation == quick_append && ! ar_truncate)
655 char **chk;
657 for (chk = files; chk != NULL && *chk != '\0'; chk++)
659 if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
661 operation = replace;
662 break;
667 if (operation == quick_append)
669 /* Note that quick appending to a non-existent archive creates it,
670 even if there are no files to append. */
671 do_quick_append (inarch_filename, files);
672 xexit (0);
674 #endif
676 arch = open_inarch (inarch_filename,
677 files == NULL ? (char *) NULL : files[0]);
679 switch (operation)
681 case print_table:
682 map_over_members (arch, print_descr, files, file_count);
683 break;
685 case print_files:
686 map_over_members (arch, print_contents, files, file_count);
687 break;
689 case extract:
690 map_over_members (arch, extract_file, files, file_count);
691 break;
693 case delete:
694 if (files != NULL)
695 delete_members (arch, files);
696 else
697 output_filename = NULL;
698 break;
700 case move:
701 if (files != NULL)
702 move_members (arch, files);
703 else
704 output_filename = NULL;
705 break;
707 case replace:
708 case quick_append:
709 if (files != NULL || write_armap > 0)
710 replace_members (arch, files, operation == quick_append);
711 else
712 output_filename = NULL;
713 break;
715 /* Shouldn't happen! */
716 default:
717 /* xgettext:c-format */
718 fatal (_("internal error -- this option not implemented"));
722 END_PROGRESS (program_name);
724 xexit (0);
725 return 0;
728 bfd *
729 open_inarch (archive_filename, file)
730 const char *archive_filename;
731 const char *file;
733 const char *target;
734 bfd **last_one;
735 bfd *next_one;
736 struct stat sbuf;
737 bfd *arch;
738 char **matching;
740 bfd_set_error (bfd_error_no_error);
742 target = NULL;
744 if (stat (archive_filename, &sbuf) != 0)
746 #if !defined(__GO32__) || defined(__DJGPP__)
748 /* FIXME: I don't understand why this fragment was ifndef'ed
749 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
750 stat() works just fine in v2.x, so I think this should be
751 removed. For now, I enable it for DJGPP v2. -- EZ. */
753 /* KLUDGE ALERT! Temporary fix until I figger why
754 stat() is wrong ... think it's buried in GO32's IDT - Jax */
755 if (errno != ENOENT)
756 bfd_fatal (archive_filename);
757 #endif
759 if (!operation_alters_arch)
761 fprintf (stderr, "%s: ", program_name);
762 perror (archive_filename);
763 maybequit ();
764 return NULL;
767 /* Try to figure out the target to use for the archive from the
768 first object on the list. */
769 if (file != NULL)
771 bfd *obj;
773 obj = bfd_openr (file, NULL);
774 if (obj != NULL)
776 if (bfd_check_format (obj, bfd_object))
777 target = bfd_get_target (obj);
778 (void) bfd_close (obj);
782 /* Create an empty archive. */
783 arch = bfd_openw (archive_filename, target);
784 if (arch == NULL
785 || ! bfd_set_format (arch, bfd_archive)
786 || ! bfd_close (arch))
787 bfd_fatal (archive_filename);
789 /* If we die creating a new archive, don't leave it around. */
790 output_filename = archive_filename;
793 arch = bfd_openr (archive_filename, target);
794 if (arch == NULL)
796 bloser:
797 bfd_fatal (archive_filename);
800 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
802 bfd_nonfatal (archive_filename);
803 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
805 list_matching_formats (matching);
806 free (matching);
808 xexit (1);
811 last_one = &(arch->next);
812 /* Read all the contents right away, regardless. */
813 for (next_one = bfd_openr_next_archived_file (arch, NULL);
814 next_one;
815 next_one = bfd_openr_next_archived_file (arch, next_one))
817 PROGRESS (1);
818 *last_one = next_one;
819 last_one = &next_one->next;
821 *last_one = (bfd *) NULL;
822 if (bfd_get_error () != bfd_error_no_more_archived_files)
823 goto bloser;
824 return arch;
827 static void
828 print_contents (abfd)
829 bfd *abfd;
831 int ncopied = 0;
832 char *cbuf = xmalloc (BUFSIZE);
833 struct stat buf;
834 long size;
835 if (bfd_stat_arch_elt (abfd, &buf) != 0)
836 /* xgettext:c-format */
837 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
839 if (verbose)
840 /* xgettext:c-format */
841 printf (_("\n<member %s>\n\n"), bfd_get_filename (abfd));
843 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
845 size = buf.st_size;
846 while (ncopied < size)
849 int nread;
850 int tocopy = size - ncopied;
851 if (tocopy > BUFSIZE)
852 tocopy = BUFSIZE;
854 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
855 if (nread != tocopy)
856 /* xgettext:c-format */
857 fatal (_("%s is not a valid archive"),
858 bfd_get_filename (bfd_my_archive (abfd)));
859 fwrite (cbuf, 1, nread, stdout);
860 ncopied += tocopy;
862 free (cbuf);
865 /* Extract a member of the archive into its own file.
867 We defer opening the new file until after we have read a BUFSIZ chunk of the
868 old one, since we know we have just read the archive header for the old
869 one. Since most members are shorter than BUFSIZ, this means we will read
870 the old header, read the old data, write a new inode for the new file, and
871 write the new data, and be done. This 'optimization' is what comes from
872 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
873 Gilmore */
875 void
876 extract_file (abfd)
877 bfd *abfd;
879 FILE *ostream;
880 char *cbuf = xmalloc (BUFSIZE);
881 int nread, tocopy;
882 long ncopied = 0;
883 long size;
884 struct stat buf;
886 if (bfd_stat_arch_elt (abfd, &buf) != 0)
887 /* xgettext:c-format */
888 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
889 size = buf.st_size;
891 if (size < 0)
892 /* xgettext:c-format */
893 fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
895 if (verbose)
896 printf ("x - %s\n", bfd_get_filename (abfd));
898 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
900 ostream = NULL;
901 if (size == 0)
903 /* Seems like an abstraction violation, eh? Well it's OK! */
904 output_filename = bfd_get_filename (abfd);
906 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
907 if (ostream == NULL)
909 perror (bfd_get_filename (abfd));
910 xexit (1);
913 output_file = ostream;
915 else
916 while (ncopied < size)
918 tocopy = size - ncopied;
919 if (tocopy > BUFSIZE)
920 tocopy = BUFSIZE;
922 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
923 if (nread != tocopy)
924 /* xgettext:c-format */
925 fatal (_("%s is not a valid archive"),
926 bfd_get_filename (bfd_my_archive (abfd)));
928 /* See comment above; this saves disk arm motion */
929 if (ostream == NULL)
931 /* Seems like an abstraction violation, eh? Well it's OK! */
932 output_filename = bfd_get_filename (abfd);
934 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
935 if (ostream == NULL)
937 perror (bfd_get_filename (abfd));
938 xexit (1);
941 output_file = ostream;
943 fwrite (cbuf, 1, nread, ostream);
944 ncopied += tocopy;
947 if (ostream != NULL)
948 fclose (ostream);
950 output_file = NULL;
951 output_filename = NULL;
953 chmod (bfd_get_filename (abfd), buf.st_mode);
955 if (preserve_dates)
956 set_times (bfd_get_filename (abfd), &buf);
958 free (cbuf);
961 #if 0
963 /* We don't use this anymore. Too many systems expect ar to rebuild
964 the symbol table even when q is used. */
966 /* Just do it quickly; don't worry about dups, armap, or anything like that */
968 static void
969 do_quick_append (archive_filename, files_to_append)
970 const char *archive_filename;
971 char **files_to_append;
973 FILE *ofile, *ifile;
974 char *buf = xmalloc (BUFSIZE);
975 long tocopy, thistime;
976 bfd *temp;
977 struct stat sbuf;
978 boolean newfile = false;
979 bfd_set_error (bfd_error_no_error);
981 if (stat (archive_filename, &sbuf) != 0)
984 #if !defined(__GO32__) || defined(__DJGPP__)
986 /* FIXME: I don't understand why this fragment was ifndef'ed
987 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
988 stat() works just fine in v2.x, so I think this should be
989 removed. For now, I enable it for DJGPP v2.
991 (And yes, I know this is all unused, but somebody, someday,
992 might wish to resurrect this again... -- EZ. */
994 /* KLUDGE ALERT! Temporary fix until I figger why
995 stat() is wrong ... think it's buried in GO32's IDT - Jax */
997 if (errno != ENOENT)
998 bfd_fatal (archive_filename);
999 #endif
1001 newfile = true;
1004 ofile = fopen (archive_filename, FOPEN_AUB);
1005 if (ofile == NULL)
1007 perror (program_name);
1008 xexit (1);
1011 temp = bfd_openr (archive_filename, NULL);
1012 if (temp == NULL)
1014 bfd_fatal (archive_filename);
1016 if (newfile == false)
1018 if (bfd_check_format (temp, bfd_archive) != true)
1019 /* xgettext:c-format */
1020 fatal (_("%s is not an archive"), archive_filename);
1022 else
1024 fwrite (ARMAG, 1, SARMAG, ofile);
1025 if (!silent_create)
1026 /* xgettext:c-format */
1027 non_fatal (_("creating %s"), archive_filename);
1030 if (ar_truncate)
1031 temp->flags |= BFD_TRADITIONAL_FORMAT;
1033 /* assume it's an achive, go straight to the end, sans $200 */
1034 fseek (ofile, 0, 2);
1036 for (; files_to_append && *files_to_append; ++files_to_append)
1038 struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
1039 if (hdr == NULL)
1041 bfd_fatal (*files_to_append);
1044 BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
1046 ifile = fopen (*files_to_append, FOPEN_RB);
1047 if (ifile == NULL)
1049 bfd_nonfatal (*files_to_append);
1052 if (stat (*files_to_append, &sbuf) != 0)
1054 bfd_nonfatal (*files_to_append);
1057 tocopy = sbuf.st_size;
1059 /* XXX should do error-checking! */
1060 fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
1062 while (tocopy > 0)
1064 thistime = tocopy;
1065 if (thistime > BUFSIZE)
1066 thistime = BUFSIZE;
1067 fread (buf, 1, thistime, ifile);
1068 fwrite (buf, 1, thistime, ofile);
1069 tocopy -= thistime;
1071 fclose (ifile);
1072 if ((sbuf.st_size % 2) == 1)
1073 putc ('\012', ofile);
1075 fclose (ofile);
1076 bfd_close (temp);
1077 free (buf);
1080 #endif /* 0 */
1082 static void
1083 write_archive (iarch)
1084 bfd *iarch;
1086 bfd *obfd;
1087 char *old_name, *new_name;
1088 bfd *contents_head = iarch->next;
1090 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1091 strcpy (old_name, bfd_get_filename (iarch));
1092 new_name = make_tempname (old_name);
1094 output_filename = new_name;
1096 obfd = bfd_openw (new_name, bfd_get_target (iarch));
1098 if (obfd == NULL)
1099 bfd_fatal (old_name);
1101 output_bfd = obfd;
1103 bfd_set_format (obfd, bfd_archive);
1105 /* Request writing the archive symbol table unless we've
1106 been explicitly requested not to. */
1107 obfd->has_armap = write_armap >= 0;
1109 if (ar_truncate)
1111 /* This should really use bfd_set_file_flags, but that rejects
1112 archives. */
1113 obfd->flags |= BFD_TRADITIONAL_FORMAT;
1116 if (bfd_set_archive_head (obfd, contents_head) != true)
1117 bfd_fatal (old_name);
1119 if (!bfd_close (obfd))
1120 bfd_fatal (old_name);
1122 output_bfd = NULL;
1123 output_filename = NULL;
1125 /* We don't care if this fails; we might be creating the archive. */
1126 bfd_close (iarch);
1128 if (smart_rename (new_name, old_name, 0) != 0)
1129 xexit (1);
1132 /* Return a pointer to the pointer to the entry which should be rplacd'd
1133 into when altering. DEFAULT_POS should be how to interpret pos_default,
1134 and should be a pos value. */
1136 static bfd **
1137 get_pos_bfd (contents, default_pos, default_posname)
1138 bfd **contents;
1139 enum pos default_pos;
1140 const char *default_posname;
1142 bfd **after_bfd = contents;
1143 enum pos realpos;
1144 const char *realposname;
1146 if (postype == pos_default)
1148 realpos = default_pos;
1149 realposname = default_posname;
1151 else
1153 realpos = postype;
1154 realposname = posname;
1157 if (realpos == pos_end)
1159 while (*after_bfd)
1160 after_bfd = &((*after_bfd)->next);
1162 else
1164 for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1165 if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1167 if (realpos == pos_after)
1168 after_bfd = &(*after_bfd)->next;
1169 break;
1172 return after_bfd;
1175 static void
1176 delete_members (arch, files_to_delete)
1177 bfd *arch;
1178 char **files_to_delete;
1180 bfd **current_ptr_ptr;
1181 boolean found;
1182 boolean something_changed = false;
1183 int match_count;
1185 for (; *files_to_delete != NULL; ++files_to_delete)
1187 /* In a.out systems, the armap is optional. It's also called
1188 __.SYMDEF. So if the user asked to delete it, we should remember
1189 that fact. This isn't quite right for COFF systems (where
1190 __.SYMDEF might be regular member), but it's very unlikely
1191 to be a problem. FIXME */
1193 if (!strcmp (*files_to_delete, "__.SYMDEF"))
1195 arch->has_armap = false;
1196 write_armap = -1;
1197 continue;
1200 found = false;
1201 match_count = 0;
1202 current_ptr_ptr = &(arch->next);
1203 while (*current_ptr_ptr)
1205 if (FILENAME_CMP (normalize (*files_to_delete, arch),
1206 (*current_ptr_ptr)->filename) == 0)
1208 ++match_count;
1209 if (counted_name_mode
1210 && match_count != counted_name_counter)
1212 /* Counting, and didn't match on count; go on to the
1213 next one. */
1215 else
1217 found = true;
1218 something_changed = true;
1219 if (verbose)
1220 printf ("d - %s\n",
1221 *files_to_delete);
1222 *current_ptr_ptr = ((*current_ptr_ptr)->next);
1223 goto next_file;
1227 current_ptr_ptr = &((*current_ptr_ptr)->next);
1230 if (verbose && found == false)
1232 /* xgettext:c-format */
1233 printf (_("No member named `%s'\n"), *files_to_delete);
1235 next_file:
1239 if (something_changed == true)
1240 write_archive (arch);
1241 else
1242 output_filename = NULL;
1246 /* Reposition existing members within an archive */
1248 static void
1249 move_members (arch, files_to_move)
1250 bfd *arch;
1251 char **files_to_move;
1253 bfd **after_bfd; /* New entries go after this one */
1254 bfd **current_ptr_ptr; /* cdr pointer into contents */
1256 for (; *files_to_move; ++files_to_move)
1258 current_ptr_ptr = &(arch->next);
1259 while (*current_ptr_ptr)
1261 bfd *current_ptr = *current_ptr_ptr;
1262 if (FILENAME_CMP (normalize (*files_to_move, arch),
1263 current_ptr->filename) == 0)
1265 /* Move this file to the end of the list - first cut from
1266 where it is. */
1267 bfd *link;
1268 *current_ptr_ptr = current_ptr->next;
1270 /* Now glue to end */
1271 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1272 link = *after_bfd;
1273 *after_bfd = current_ptr;
1274 current_ptr->next = link;
1276 if (verbose)
1277 printf ("m - %s\n", *files_to_move);
1279 goto next_file;
1282 current_ptr_ptr = &((*current_ptr_ptr)->next);
1284 /* xgettext:c-format */
1285 fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1287 next_file:;
1290 write_archive (arch);
1293 /* Ought to default to replacing in place, but this is existing practice! */
1295 static void
1296 replace_members (arch, files_to_move, quick)
1297 bfd *arch;
1298 char **files_to_move;
1299 boolean quick;
1301 boolean changed = false;
1302 bfd **after_bfd; /* New entries go after this one */
1303 bfd *current;
1304 bfd **current_ptr;
1306 while (files_to_move && *files_to_move)
1308 if (! quick)
1310 current_ptr = &arch->next;
1311 while (*current_ptr)
1313 current = *current_ptr;
1315 /* For compatibility with existing ar programs, we
1316 permit the same file to be added multiple times. */
1317 if (FILENAME_CMP (normalize (*files_to_move, arch),
1318 normalize (current->filename, arch)) == 0
1319 && current->arelt_data != NULL)
1321 if (newer_only)
1323 struct stat fsbuf, asbuf;
1325 if (stat (*files_to_move, &fsbuf) != 0)
1327 if (errno != ENOENT)
1328 bfd_fatal (*files_to_move);
1329 goto next_file;
1331 if (bfd_stat_arch_elt (current, &asbuf) != 0)
1332 /* xgettext:c-format */
1333 fatal (_("internal stat error on %s"),
1334 current->filename);
1336 if (fsbuf.st_mtime <= asbuf.st_mtime)
1337 goto next_file;
1340 after_bfd = get_pos_bfd (&arch->next, pos_after,
1341 current->filename);
1342 if (ar_emul_replace (after_bfd, *files_to_move,
1343 verbose))
1345 /* Snip out this entry from the chain. */
1346 *current_ptr = (*current_ptr)->next;
1347 changed = true;
1350 goto next_file;
1352 current_ptr = &(current->next);
1356 /* Add to the end of the archive. */
1357 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1358 if (ar_emul_append (after_bfd, *files_to_move, verbose))
1359 changed = true;
1361 next_file:;
1363 files_to_move++;
1366 if (changed)
1367 write_archive (arch);
1368 else
1369 output_filename = NULL;
1372 static void
1373 ranlib_only (archname)
1374 const char *archname;
1376 bfd *arch;
1378 write_armap = 1;
1379 arch = open_inarch (archname, (char *) NULL);
1380 if (arch == NULL)
1381 xexit (1);
1382 write_archive (arch);
1385 /* Update the timestamp of the symbol map of an archive. */
1387 static void
1388 ranlib_touch (archname)
1389 const char *archname;
1391 #ifdef __GO32__
1392 /* I don't think updating works on go32. */
1393 ranlib_only (archname);
1394 #else
1395 int f;
1396 bfd *arch;
1397 char **matching;
1399 f = open (archname, O_RDWR | O_BINARY, 0);
1400 if (f < 0)
1402 bfd_set_error (bfd_error_system_call);
1403 bfd_fatal (archname);
1406 arch = bfd_fdopenr (archname, (const char *) NULL, f);
1407 if (arch == NULL)
1408 bfd_fatal (archname);
1409 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1411 bfd_nonfatal (archname);
1412 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1414 list_matching_formats (matching);
1415 free (matching);
1417 xexit (1);
1420 if (! bfd_has_map (arch))
1421 /* xgettext:c-format */
1422 fatal (_("%s: no archive map to update"), archname);
1424 bfd_update_armap_timestamp (arch);
1426 if (! bfd_close (arch))
1427 bfd_fatal (archname);
1428 #endif
1431 /* Things which are interesting to map over all or some of the files: */
1433 static void
1434 print_descr (abfd)
1435 bfd *abfd;
1437 print_arelt_descr (stdout, abfd, verbose);