* doc/c-xtensa.texi (Xtensa Automatic Alignment): Remove statements
[binutils.git] / binutils / ar.c
blob720ced73e9828c269f5302a8e777150bc2c6545e
1 /* ar.c - Archive modify and extract.
2 Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2006, 2007
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 consistent. */
29 #include "sysdep.h"
30 #include "bfd.h"
31 #include "libiberty.h"
32 #include "progress.h"
33 #include "aout/ar.h"
34 #include "libbfd.h"
35 #include "bucomm.h"
36 #include "arsup.h"
37 #include "filenames.h"
38 #include "binemul.h"
39 #include <sys/stat.h>
41 #ifdef __GO32___
42 #define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
43 #else
44 #define EXT_NAME_LEN 6 /* ditto for *NIX */
45 #endif
47 /* We need to open files in binary modes on system where that makes a
48 difference. */
49 #ifndef O_BINARY
50 #define O_BINARY 0
51 #endif
53 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
55 struct ar_hdr *
56 bfd_special_undocumented_glue (bfd * abfd, const char *filename);
58 /* Static declarations */
60 static void mri_emul (void);
61 static const char *normalize (const char *, bfd *);
62 static void remove_output (void);
63 static void map_over_members (bfd *, void (*)(bfd *), char **, int);
64 static void print_contents (bfd * member);
65 static void delete_members (bfd *, char **files_to_delete);
67 static void move_members (bfd *, char **files_to_move);
68 static void replace_members
69 (bfd *, char **files_to_replace, bfd_boolean quick);
70 static void print_descr (bfd * abfd);
71 static void write_archive (bfd *);
72 static int ranlib_only (const char *archname);
73 static int ranlib_touch (const char *archname);
74 static void usage (int);
76 /** Globals and flags */
78 static int mri_mode;
80 /* This flag distinguishes between ar and ranlib:
81 1 means this is 'ranlib'; 0 means this is 'ar'.
82 -1 means if we should use argv[0] to decide. */
83 extern int is_ranlib;
85 /* Nonzero means don't warn about creating the archive file if necessary. */
86 int silent_create = 0;
88 /* Nonzero means describe each action performed. */
89 int verbose = 0;
91 /* Nonzero means preserve dates of members when extracting them. */
92 int preserve_dates = 0;
94 /* Nonzero means don't replace existing members whose dates are more recent
95 than the corresponding files. */
96 int newer_only = 0;
98 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
99 member). -1 means we've been explicitly asked to not write a symbol table;
100 +1 means we've been explicitly asked to write it;
101 0 is the default.
102 Traditionally, the default in BSD has been to not write the table.
103 However, for POSIX.2 compliance the default is now to write a symbol table
104 if any of the members are object files. */
105 int write_armap = 0;
107 /* Nonzero means it's the name of an existing member; position new or moved
108 files with respect to this one. */
109 char *posname = NULL;
111 /* Sez how to use `posname': pos_before means position before that member.
112 pos_after means position after that member. pos_end means always at end.
113 pos_default means default appropriately. For the latter two, `posname'
114 should also be zero. */
115 enum pos
117 pos_default, pos_before, pos_after, pos_end
118 } postype = pos_default;
120 static bfd **
121 get_pos_bfd (bfd **, enum pos, const char *);
123 /* For extract/delete only. If COUNTED_NAME_MODE is TRUE, we only
124 extract the COUNTED_NAME_COUNTER instance of that name. */
125 static bfd_boolean counted_name_mode = 0;
126 static int counted_name_counter = 0;
128 /* Whether to truncate names of files stored in the archive. */
129 static bfd_boolean ar_truncate = FALSE;
131 /* Whether to use a full file name match when searching an archive.
132 This is convenient for archives created by the Microsoft lib
133 program. */
134 static bfd_boolean full_pathname = FALSE;
136 int interactive = 0;
138 static void
139 mri_emul (void)
141 interactive = isatty (fileno (stdin));
142 yyparse ();
145 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
146 COUNT is the length of the FILES chain; FUNCTION is called on each entry
147 whose name matches one in FILES. */
149 static void
150 map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
152 bfd *head;
153 int match_count;
155 if (count == 0)
157 for (head = arch->next; head; head = head->next)
159 PROGRESS (1);
160 function (head);
162 return;
165 /* This may appear to be a baroque way of accomplishing what we want.
166 However we have to iterate over the filenames in order to notice where
167 a filename is requested but does not exist in the archive. Ditto
168 mapping over each file each time -- we want to hack multiple
169 references. */
171 for (; count > 0; files++, count--)
173 bfd_boolean found = FALSE;
175 match_count = 0;
176 for (head = arch->next; head; head = head->next)
178 PROGRESS (1);
179 if (head->filename == NULL)
181 /* Some archive formats don't get the filenames filled in
182 until the elements are opened. */
183 struct stat buf;
184 bfd_stat_arch_elt (head, &buf);
186 if ((head->filename != NULL) &&
187 (!FILENAME_CMP (normalize (*files, arch), head->filename)))
189 ++match_count;
190 if (counted_name_mode
191 && match_count != counted_name_counter)
193 /* Counting, and didn't match on count; go on to the
194 next one. */
195 continue;
198 found = TRUE;
199 function (head);
202 if (!found)
203 /* xgettext:c-format */
204 fprintf (stderr, _("no entry %s in archive\n"), *files);
208 bfd_boolean operation_alters_arch = FALSE;
210 static void
211 usage (int help)
213 FILE *s;
215 s = help ? stdout : stderr;
217 if (! is_ranlib)
219 /* xgettext:c-format */
220 fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
221 program_name);
222 /* xgettext:c-format */
223 fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
224 fprintf (s, _(" commands:\n"));
225 fprintf (s, _(" d - delete file(s) from the archive\n"));
226 fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
227 fprintf (s, _(" p - print file(s) found in the archive\n"));
228 fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
229 fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
230 fprintf (s, _(" t - display contents of archive\n"));
231 fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
232 fprintf (s, _(" command specific modifiers:\n"));
233 fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
234 fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
235 fprintf (s, _(" [N] - use instance [count] of name\n"));
236 fprintf (s, _(" [f] - truncate inserted file names\n"));
237 fprintf (s, _(" [P] - use full path names when matching\n"));
238 fprintf (s, _(" [o] - preserve original dates\n"));
239 fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
240 fprintf (s, _(" generic modifiers:\n"));
241 fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
242 fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
243 fprintf (s, _(" [S] - do not build a symbol table\n"));
244 fprintf (s, _(" [v] - be verbose\n"));
245 fprintf (s, _(" [V] - display the version number\n"));
246 fprintf (s, _(" @<file> - read options from <file>\n"));
248 ar_emul_usage (s);
250 else
252 /* xgettext:c-format */
253 fprintf (s, _("Usage: %s [options] archive\n"), program_name);
254 fprintf (s, _(" Generate an index to speed access to archives\n"));
255 fprintf (s, _(" The options are:\n\
256 @<file> Read options from <file>\n\
257 -h --help Print this help message\n\
258 -V --version Print version information\n"));
261 list_supported_targets (program_name, s);
263 if (REPORT_BUGS_TO[0] && help)
264 fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
266 xexit (help ? 0 : 1);
269 /* Normalize a file name specified on the command line into a file
270 name which we will use in an archive. */
272 static const char *
273 normalize (const char *file, bfd *abfd)
275 const char *filename;
277 if (full_pathname)
278 return file;
280 filename = strrchr (file, '/');
281 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
283 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
284 char *bslash = strrchr (file, '\\');
285 if (filename == NULL || (bslash != NULL && bslash > filename))
286 filename = bslash;
287 if (filename == NULL && file[0] != '\0' && file[1] == ':')
288 filename = file + 1;
290 #endif
291 if (filename != (char *) NULL)
292 filename++;
293 else
294 filename = file;
296 if (ar_truncate
297 && abfd != NULL
298 && strlen (filename) > abfd->xvec->ar_max_namelen)
300 char *s;
302 /* Space leak. */
303 s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
304 memcpy (s, filename, abfd->xvec->ar_max_namelen);
305 s[abfd->xvec->ar_max_namelen] = '\0';
306 filename = s;
309 return filename;
312 /* Remove any output file. This is only called via xatexit. */
314 static const char *output_filename = NULL;
315 static FILE *output_file = NULL;
316 static bfd *output_bfd = NULL;
318 static void
319 remove_output (void)
321 if (output_filename != NULL)
323 if (output_bfd != NULL)
324 bfd_cache_close (output_bfd);
325 if (output_file != NULL)
326 fclose (output_file);
327 unlink_if_ordinary (output_filename);
331 /* The option parsing should be in its own function.
332 It will be when I have getopt working. */
334 int main (int, char **);
337 main (int argc, char **argv)
339 char *arg_ptr;
340 char c;
341 enum
343 none = 0, delete, replace, print_table,
344 print_files, extract, move, quick_append
345 } operation = none;
346 int arg_index;
347 char **files;
348 int file_count;
349 char *inarch_filename;
350 int show_version;
351 int i;
352 int do_posix = 0;
354 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
355 setlocale (LC_MESSAGES, "");
356 #endif
357 #if defined (HAVE_SETLOCALE)
358 setlocale (LC_CTYPE, "");
359 #endif
360 bindtextdomain (PACKAGE, LOCALEDIR);
361 textdomain (PACKAGE);
363 program_name = argv[0];
364 xmalloc_set_program_name (program_name);
366 expandargv (&argc, &argv);
368 if (is_ranlib < 0)
370 char *temp;
372 temp = strrchr (program_name, '/');
373 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
375 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
376 char *bslash = strrchr (program_name, '\\');
377 if (temp == NULL || (bslash != NULL && bslash > temp))
378 temp = bslash;
379 if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
380 temp = program_name + 1;
382 #endif
383 if (temp == NULL)
384 temp = program_name;
385 else
386 ++temp;
387 if (strlen (temp) >= 6
388 && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
389 is_ranlib = 1;
390 else
391 is_ranlib = 0;
394 if (argc > 1 && argv[1][0] == '-')
396 if (strcmp (argv[1], "--help") == 0)
397 usage (1);
398 else if (strcmp (argv[1], "--version") == 0)
400 if (is_ranlib)
401 print_version ("ranlib");
402 else
403 print_version ("ar");
407 START_PROGRESS (program_name, 0);
409 bfd_init ();
410 set_default_bfd_target ();
412 show_version = 0;
414 xatexit (remove_output);
416 for (i = 1; i < argc; i++)
417 if (! ar_emul_parse_arg (argv[i]))
418 break;
419 argv += (i - 1);
420 argc -= (i - 1);
422 if (is_ranlib)
424 int status = 0;
425 bfd_boolean touch = FALSE;
427 if (argc < 2
428 || strcmp (argv[1], "--help") == 0
429 || strcmp (argv[1], "-h") == 0
430 || strcmp (argv[1], "-H") == 0)
431 usage (0);
432 if (strcmp (argv[1], "-V") == 0
433 || strcmp (argv[1], "-v") == 0
434 || CONST_STRNEQ (argv[1], "--v"))
435 print_version ("ranlib");
436 arg_index = 1;
437 if (strcmp (argv[1], "-t") == 0)
439 ++arg_index;
440 touch = TRUE;
442 while (arg_index < argc)
444 if (! touch)
445 status |= ranlib_only (argv[arg_index]);
446 else
447 status |= ranlib_touch (argv[arg_index]);
448 ++arg_index;
450 xexit (status);
453 if (argc == 2 && strcmp (argv[1], "-M") == 0)
455 mri_emul ();
456 xexit (0);
459 if (argc < 2)
460 usage (0);
462 arg_index = 1;
463 arg_ptr = argv[arg_index];
465 if (*arg_ptr == '-')
467 /* When the first option starts with '-' we support POSIX-compatible
468 option parsing. */
469 do_posix = 1;
470 ++arg_ptr; /* compatibility */
475 while ((c = *arg_ptr++) != '\0')
477 switch (c)
479 case 'd':
480 case 'm':
481 case 'p':
482 case 'q':
483 case 'r':
484 case 't':
485 case 'x':
486 if (operation != none)
487 fatal (_("two different operation options specified"));
488 switch (c)
490 case 'd':
491 operation = delete;
492 operation_alters_arch = TRUE;
493 break;
494 case 'm':
495 operation = move;
496 operation_alters_arch = TRUE;
497 break;
498 case 'p':
499 operation = print_files;
500 break;
501 case 'q':
502 operation = quick_append;
503 operation_alters_arch = TRUE;
504 break;
505 case 'r':
506 operation = replace;
507 operation_alters_arch = TRUE;
508 break;
509 case 't':
510 operation = print_table;
511 break;
512 case 'x':
513 operation = extract;
514 break;
516 case 'l':
517 break;
518 case 'c':
519 silent_create = 1;
520 break;
521 case 'o':
522 preserve_dates = 1;
523 break;
524 case 'V':
525 show_version = TRUE;
526 break;
527 case 's':
528 write_armap = 1;
529 break;
530 case 'S':
531 write_armap = -1;
532 break;
533 case 'u':
534 newer_only = 1;
535 break;
536 case 'v':
537 verbose = 1;
538 break;
539 case 'a':
540 postype = pos_after;
541 break;
542 case 'b':
543 postype = pos_before;
544 break;
545 case 'i':
546 postype = pos_before;
547 break;
548 case 'M':
549 mri_mode = 1;
550 break;
551 case 'N':
552 counted_name_mode = TRUE;
553 break;
554 case 'f':
555 ar_truncate = TRUE;
556 break;
557 case 'P':
558 full_pathname = TRUE;
559 break;
560 default:
561 /* xgettext:c-format */
562 non_fatal (_("illegal option -- %c"), c);
563 usage (0);
567 /* With POSIX-compatible option parsing continue with the next
568 argument if it starts with '-'. */
569 if (do_posix && arg_index + 1 < argc && argv[arg_index + 1][0] == '-')
570 arg_ptr = argv[++arg_index] + 1;
571 else
572 do_posix = 0;
574 while (do_posix);
576 if (show_version)
577 print_version ("ar");
579 ++arg_index;
580 if (arg_index >= argc)
581 usage (0);
583 if (mri_mode)
585 mri_emul ();
587 else
589 bfd *arch;
591 /* We don't use do_quick_append any more. Too many systems
592 expect ar to always rebuild the symbol table even when q is
593 used. */
595 /* We can't write an armap when using ar q, so just do ar r
596 instead. */
597 if (operation == quick_append && write_armap)
598 operation = replace;
600 if ((operation == none || operation == print_table)
601 && write_armap == 1)
602 xexit (ranlib_only (argv[arg_index]));
604 if (operation == none)
605 fatal (_("no operation specified"));
607 if (newer_only && operation != replace)
608 fatal (_("`u' is only meaningful with the `r' option."));
610 if (postype != pos_default)
611 posname = argv[arg_index++];
613 if (counted_name_mode)
615 if (operation != extract && operation != delete)
616 fatal (_("`N' is only meaningful with the `x' and `d' options."));
617 counted_name_counter = atoi (argv[arg_index++]);
618 if (counted_name_counter <= 0)
619 fatal (_("Value for `N' must be positive."));
622 inarch_filename = argv[arg_index++];
624 files = arg_index < argc ? argv + arg_index : NULL;
625 file_count = argc - arg_index;
627 arch = open_inarch (inarch_filename,
628 files == NULL ? (char *) NULL : files[0]);
630 switch (operation)
632 case print_table:
633 map_over_members (arch, print_descr, files, file_count);
634 break;
636 case print_files:
637 map_over_members (arch, print_contents, files, file_count);
638 break;
640 case extract:
641 map_over_members (arch, extract_file, files, file_count);
642 break;
644 case delete:
645 if (files != NULL)
646 delete_members (arch, files);
647 else
648 output_filename = NULL;
649 break;
651 case move:
652 if (files != NULL)
653 move_members (arch, files);
654 else
655 output_filename = NULL;
656 break;
658 case replace:
659 case quick_append:
660 if (files != NULL || write_armap > 0)
661 replace_members (arch, files, operation == quick_append);
662 else
663 output_filename = NULL;
664 break;
666 /* Shouldn't happen! */
667 default:
668 /* xgettext:c-format */
669 fatal (_("internal error -- this option not implemented"));
673 END_PROGRESS (program_name);
675 xexit (0);
676 return 0;
679 bfd *
680 open_inarch (const char *archive_filename, const char *file)
682 const char *target;
683 bfd **last_one;
684 bfd *next_one;
685 struct stat sbuf;
686 bfd *arch;
687 char **matching;
689 bfd_set_error (bfd_error_no_error);
691 target = NULL;
693 if (stat (archive_filename, &sbuf) != 0)
695 #if !defined(__GO32__) || defined(__DJGPP__)
697 /* FIXME: I don't understand why this fragment was ifndef'ed
698 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
699 stat() works just fine in v2.x, so I think this should be
700 removed. For now, I enable it for DJGPP v2. -- EZ. */
702 /* KLUDGE ALERT! Temporary fix until I figger why
703 stat() is wrong ... think it's buried in GO32's IDT - Jax */
704 if (errno != ENOENT)
705 bfd_fatal (archive_filename);
706 #endif
708 if (!operation_alters_arch)
710 fprintf (stderr, "%s: ", program_name);
711 perror (archive_filename);
712 maybequit ();
713 return NULL;
716 /* Try to figure out the target to use for the archive from the
717 first object on the list. */
718 if (file != NULL)
720 bfd *obj;
722 obj = bfd_openr (file, NULL);
723 if (obj != NULL)
725 if (bfd_check_format (obj, bfd_object))
726 target = bfd_get_target (obj);
727 (void) bfd_close (obj);
731 /* Create an empty archive. */
732 arch = bfd_openw (archive_filename, target);
733 if (arch == NULL
734 || ! bfd_set_format (arch, bfd_archive)
735 || ! bfd_close (arch))
736 bfd_fatal (archive_filename);
737 else if (!silent_create)
738 non_fatal (_("creating %s"), archive_filename);
740 /* If we die creating a new archive, don't leave it around. */
741 output_filename = archive_filename;
744 arch = bfd_openr (archive_filename, target);
745 if (arch == NULL)
747 bloser:
748 bfd_fatal (archive_filename);
751 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
753 bfd_nonfatal (archive_filename);
754 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
756 list_matching_formats (matching);
757 free (matching);
759 xexit (1);
762 last_one = &(arch->next);
763 /* Read all the contents right away, regardless. */
764 for (next_one = bfd_openr_next_archived_file (arch, NULL);
765 next_one;
766 next_one = bfd_openr_next_archived_file (arch, next_one))
768 PROGRESS (1);
769 *last_one = next_one;
770 last_one = &next_one->next;
772 *last_one = (bfd *) NULL;
773 if (bfd_get_error () != bfd_error_no_more_archived_files)
774 goto bloser;
775 return arch;
778 static void
779 print_contents (bfd *abfd)
781 size_t ncopied = 0;
782 char *cbuf = xmalloc (BUFSIZE);
783 struct stat buf;
784 size_t size;
785 if (bfd_stat_arch_elt (abfd, &buf) != 0)
786 /* xgettext:c-format */
787 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
789 if (verbose)
790 /* xgettext:c-format */
791 printf (_("\n<%s>\n\n"), bfd_get_filename (abfd));
793 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
795 size = buf.st_size;
796 while (ncopied < size)
799 size_t nread;
800 size_t tocopy = size - ncopied;
801 if (tocopy > BUFSIZE)
802 tocopy = BUFSIZE;
804 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
805 if (nread != tocopy)
806 /* xgettext:c-format */
807 fatal (_("%s is not a valid archive"),
808 bfd_get_filename (bfd_my_archive (abfd)));
810 /* fwrite in mingw32 may return int instead of size_t. Cast the
811 return value to size_t to avoid comparison between signed and
812 unsigned values. */
813 if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread)
814 fatal ("stdout: %s", strerror (errno));
815 ncopied += tocopy;
817 free (cbuf);
820 /* Extract a member of the archive into its own file.
822 We defer opening the new file until after we have read a BUFSIZ chunk of the
823 old one, since we know we have just read the archive header for the old
824 one. Since most members are shorter than BUFSIZ, this means we will read
825 the old header, read the old data, write a new inode for the new file, and
826 write the new data, and be done. This 'optimization' is what comes from
827 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
828 Gilmore */
830 void
831 extract_file (bfd *abfd)
833 FILE *ostream;
834 char *cbuf = xmalloc (BUFSIZE);
835 size_t nread, tocopy;
836 size_t ncopied = 0;
837 size_t size;
838 struct stat buf;
840 if (bfd_stat_arch_elt (abfd, &buf) != 0)
841 /* xgettext:c-format */
842 fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
843 size = buf.st_size;
845 if (verbose)
846 printf ("x - %s\n", bfd_get_filename (abfd));
848 bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
850 ostream = NULL;
851 if (size == 0)
853 /* Seems like an abstraction violation, eh? Well it's OK! */
854 output_filename = bfd_get_filename (abfd);
856 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
857 if (ostream == NULL)
859 perror (bfd_get_filename (abfd));
860 xexit (1);
863 output_file = ostream;
865 else
866 while (ncopied < size)
868 tocopy = size - ncopied;
869 if (tocopy > BUFSIZE)
870 tocopy = BUFSIZE;
872 nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
873 if (nread != tocopy)
874 /* xgettext:c-format */
875 fatal (_("%s is not a valid archive"),
876 bfd_get_filename (bfd_my_archive (abfd)));
878 /* See comment above; this saves disk arm motion */
879 if (ostream == NULL)
881 /* Seems like an abstraction violation, eh? Well it's OK! */
882 output_filename = bfd_get_filename (abfd);
884 ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
885 if (ostream == NULL)
887 perror (bfd_get_filename (abfd));
888 xexit (1);
891 output_file = ostream;
894 /* fwrite in mingw32 may return int instead of size_t. Cast
895 the return value to size_t to avoid comparison between
896 signed and unsigned values. */
897 if ((size_t) fwrite (cbuf, 1, nread, ostream) != nread)
898 fatal ("%s: %s", output_filename, strerror (errno));
899 ncopied += tocopy;
902 if (ostream != NULL)
903 fclose (ostream);
905 output_file = NULL;
906 output_filename = NULL;
908 chmod (bfd_get_filename (abfd), buf.st_mode);
910 if (preserve_dates)
912 /* Set access time to modification time. Only st_mtime is
913 initialized by bfd_stat_arch_elt. */
914 buf.st_atime = buf.st_mtime;
915 set_times (bfd_get_filename (abfd), &buf);
918 free (cbuf);
921 static void
922 write_archive (bfd *iarch)
924 bfd *obfd;
925 char *old_name, *new_name;
926 bfd *contents_head = iarch->next;
928 old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
929 strcpy (old_name, bfd_get_filename (iarch));
930 new_name = make_tempname (old_name);
932 if (new_name == NULL)
933 bfd_fatal ("could not create temporary file whilst writing archive");
935 output_filename = new_name;
937 obfd = bfd_openw (new_name, bfd_get_target (iarch));
939 if (obfd == NULL)
940 bfd_fatal (old_name);
942 output_bfd = obfd;
944 bfd_set_format (obfd, bfd_archive);
946 /* Request writing the archive symbol table unless we've
947 been explicitly requested not to. */
948 obfd->has_armap = write_armap >= 0;
950 if (ar_truncate)
952 /* This should really use bfd_set_file_flags, but that rejects
953 archives. */
954 obfd->flags |= BFD_TRADITIONAL_FORMAT;
957 if (!bfd_set_archive_head (obfd, contents_head))
958 bfd_fatal (old_name);
960 if (!bfd_close (obfd))
961 bfd_fatal (old_name);
963 output_bfd = NULL;
964 output_filename = NULL;
966 /* We don't care if this fails; we might be creating the archive. */
967 bfd_close (iarch);
969 if (smart_rename (new_name, old_name, 0) != 0)
970 xexit (1);
973 /* Return a pointer to the pointer to the entry which should be rplacd'd
974 into when altering. DEFAULT_POS should be how to interpret pos_default,
975 and should be a pos value. */
977 static bfd **
978 get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
980 bfd **after_bfd = contents;
981 enum pos realpos;
982 const char *realposname;
984 if (postype == pos_default)
986 realpos = default_pos;
987 realposname = default_posname;
989 else
991 realpos = postype;
992 realposname = posname;
995 if (realpos == pos_end)
997 while (*after_bfd)
998 after_bfd = &((*after_bfd)->next);
1000 else
1002 for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1003 if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1005 if (realpos == pos_after)
1006 after_bfd = &(*after_bfd)->next;
1007 break;
1010 return after_bfd;
1013 static void
1014 delete_members (bfd *arch, char **files_to_delete)
1016 bfd **current_ptr_ptr;
1017 bfd_boolean found;
1018 bfd_boolean something_changed = FALSE;
1019 int match_count;
1021 for (; *files_to_delete != NULL; ++files_to_delete)
1023 /* In a.out systems, the armap is optional. It's also called
1024 __.SYMDEF. So if the user asked to delete it, we should remember
1025 that fact. This isn't quite right for COFF systems (where
1026 __.SYMDEF might be regular member), but it's very unlikely
1027 to be a problem. FIXME */
1029 if (!strcmp (*files_to_delete, "__.SYMDEF"))
1031 arch->has_armap = FALSE;
1032 write_armap = -1;
1033 continue;
1036 found = FALSE;
1037 match_count = 0;
1038 current_ptr_ptr = &(arch->next);
1039 while (*current_ptr_ptr)
1041 if (FILENAME_CMP (normalize (*files_to_delete, arch),
1042 (*current_ptr_ptr)->filename) == 0)
1044 ++match_count;
1045 if (counted_name_mode
1046 && match_count != counted_name_counter)
1048 /* Counting, and didn't match on count; go on to the
1049 next one. */
1051 else
1053 found = TRUE;
1054 something_changed = TRUE;
1055 if (verbose)
1056 printf ("d - %s\n",
1057 *files_to_delete);
1058 *current_ptr_ptr = ((*current_ptr_ptr)->next);
1059 goto next_file;
1063 current_ptr_ptr = &((*current_ptr_ptr)->next);
1066 if (verbose && !found)
1068 /* xgettext:c-format */
1069 printf (_("No member named `%s'\n"), *files_to_delete);
1071 next_file:
1075 if (something_changed)
1076 write_archive (arch);
1077 else
1078 output_filename = NULL;
1082 /* Reposition existing members within an archive */
1084 static void
1085 move_members (bfd *arch, char **files_to_move)
1087 bfd **after_bfd; /* New entries go after this one */
1088 bfd **current_ptr_ptr; /* cdr pointer into contents */
1090 for (; *files_to_move; ++files_to_move)
1092 current_ptr_ptr = &(arch->next);
1093 while (*current_ptr_ptr)
1095 bfd *current_ptr = *current_ptr_ptr;
1096 if (FILENAME_CMP (normalize (*files_to_move, arch),
1097 current_ptr->filename) == 0)
1099 /* Move this file to the end of the list - first cut from
1100 where it is. */
1101 bfd *link;
1102 *current_ptr_ptr = current_ptr->next;
1104 /* Now glue to end */
1105 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1106 link = *after_bfd;
1107 *after_bfd = current_ptr;
1108 current_ptr->next = link;
1110 if (verbose)
1111 printf ("m - %s\n", *files_to_move);
1113 goto next_file;
1116 current_ptr_ptr = &((*current_ptr_ptr)->next);
1118 /* xgettext:c-format */
1119 fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1121 next_file:;
1124 write_archive (arch);
1127 /* Ought to default to replacing in place, but this is existing practice! */
1129 static void
1130 replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
1132 bfd_boolean changed = FALSE;
1133 bfd **after_bfd; /* New entries go after this one. */
1134 bfd *current;
1135 bfd **current_ptr;
1137 while (files_to_move && *files_to_move)
1139 if (! quick)
1141 current_ptr = &arch->next;
1142 while (*current_ptr)
1144 current = *current_ptr;
1146 /* For compatibility with existing ar programs, we
1147 permit the same file to be added multiple times. */
1148 if (FILENAME_CMP (normalize (*files_to_move, arch),
1149 normalize (current->filename, arch)) == 0
1150 && current->arelt_data != NULL)
1152 if (newer_only)
1154 struct stat fsbuf, asbuf;
1156 if (stat (*files_to_move, &fsbuf) != 0)
1158 if (errno != ENOENT)
1159 bfd_fatal (*files_to_move);
1160 goto next_file;
1162 if (bfd_stat_arch_elt (current, &asbuf) != 0)
1163 /* xgettext:c-format */
1164 fatal (_("internal stat error on %s"),
1165 current->filename);
1167 if (fsbuf.st_mtime <= asbuf.st_mtime)
1168 goto next_file;
1171 after_bfd = get_pos_bfd (&arch->next, pos_after,
1172 current->filename);
1173 if (ar_emul_replace (after_bfd, *files_to_move,
1174 verbose))
1176 /* Snip out this entry from the chain. */
1177 *current_ptr = (*current_ptr)->next;
1178 changed = TRUE;
1181 goto next_file;
1183 current_ptr = &(current->next);
1187 /* Add to the end of the archive. */
1188 after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1190 if (ar_emul_append (after_bfd, *files_to_move, verbose))
1191 changed = TRUE;
1193 next_file:;
1195 files_to_move++;
1198 if (changed)
1199 write_archive (arch);
1200 else
1201 output_filename = NULL;
1204 static int
1205 ranlib_only (const char *archname)
1207 bfd *arch;
1209 if (get_file_size (archname) < 1)
1210 return 1;
1211 write_armap = 1;
1212 arch = open_inarch (archname, (char *) NULL);
1213 if (arch == NULL)
1214 xexit (1);
1215 write_archive (arch);
1216 return 0;
1219 /* Update the timestamp of the symbol map of an archive. */
1221 static int
1222 ranlib_touch (const char *archname)
1224 #ifdef __GO32__
1225 /* I don't think updating works on go32. */
1226 ranlib_only (archname);
1227 #else
1228 int f;
1229 bfd *arch;
1230 char **matching;
1232 if (get_file_size (archname) < 1)
1233 return 1;
1234 f = open (archname, O_RDWR | O_BINARY, 0);
1235 if (f < 0)
1237 bfd_set_error (bfd_error_system_call);
1238 bfd_fatal (archname);
1241 arch = bfd_fdopenr (archname, (const char *) NULL, f);
1242 if (arch == NULL)
1243 bfd_fatal (archname);
1244 if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1246 bfd_nonfatal (archname);
1247 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1249 list_matching_formats (matching);
1250 free (matching);
1252 xexit (1);
1255 if (! bfd_has_map (arch))
1256 /* xgettext:c-format */
1257 fatal (_("%s: no archive map to update"), archname);
1259 bfd_update_armap_timestamp (arch);
1261 if (! bfd_close (arch))
1262 bfd_fatal (archname);
1263 #endif
1264 return 0;
1267 /* Things which are interesting to map over all or some of the files: */
1269 static void
1270 print_descr (bfd *abfd)
1272 print_arelt_descr (stdout, abfd, verbose);