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
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
30 #include "libiberty.h"
36 #include "filenames.h"
41 #define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
43 #define EXT_NAME_LEN 6 /* ditto for *NIX */
46 /* We need to open files in binary modes on system where that makes a
52 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
55 bfd_special_undocumented_glue (bfd
* abfd
, const char *filename
);
57 /* Static declarations */
59 static void mri_emul (void);
60 static const char *normalize (const char *, bfd
*);
61 static void remove_output (void);
62 static void map_over_members (bfd
*, void (*)(bfd
*), char **, int);
63 static void print_contents (bfd
* member
);
64 static void delete_members (bfd
*, char **files_to_delete
);
66 static void move_members (bfd
*, char **files_to_move
);
67 static void replace_members
68 (bfd
*, char **files_to_replace
, bfd_boolean quick
);
69 static void print_descr (bfd
* abfd
);
70 static void write_archive (bfd
*);
71 static void ranlib_only (const char *archname
);
72 static void ranlib_touch (const char *archname
);
73 static void usage (int);
75 /** Globals and flags */
79 /* This flag distinguishes between ar and ranlib:
80 1 means this is 'ranlib'; 0 means this is 'ar'.
81 -1 means if we should use argv[0] to decide. */
84 /* Nonzero means don't warn about creating the archive file if necessary. */
85 int silent_create
= 0;
87 /* Nonzero means describe each action performed. */
90 /* Nonzero means preserve dates of members when extracting them. */
91 int preserve_dates
= 0;
93 /* Nonzero means don't replace existing members whose dates are more recent
94 than the corresponding files. */
97 /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
98 member). -1 means we've been explicitly asked to not write a symbol table;
99 +1 means we've been explicitly asked to write it;
101 Traditionally, the default in BSD has been to not write the table.
102 However, for POSIX.2 compliance the default is now to write a symbol table
103 if any of the members are object files. */
106 /* Nonzero means it's the name of an existing member; position new or moved
107 files with respect to this one. */
108 char *posname
= NULL
;
110 /* Sez how to use `posname': pos_before means position before that member.
111 pos_after means position after that member. pos_end means always at end.
112 pos_default means default appropriately. For the latter two, `posname'
113 should also be zero. */
116 pos_default
, pos_before
, pos_after
, pos_end
117 } postype
= pos_default
;
120 get_pos_bfd (bfd
**, enum pos
, const char *);
122 /* For extract/delete only. If COUNTED_NAME_MODE is TRUE, we only
123 extract the COUNTED_NAME_COUNTER instance of that name. */
124 static bfd_boolean counted_name_mode
= 0;
125 static int counted_name_counter
= 0;
127 /* Whether to truncate names of files stored in the archive. */
128 static bfd_boolean ar_truncate
= FALSE
;
130 /* Whether to use a full file name match when searching an archive.
131 This is convenient for archives created by the Microsoft lib
133 static bfd_boolean full_pathname
= FALSE
;
140 interactive
= isatty (fileno (stdin
));
144 /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
145 COUNT is the length of the FILES chain; FUNCTION is called on each entry
146 whose name matches one in FILES. */
149 map_over_members (bfd
*arch
, void (*function
)(bfd
*), char **files
, int count
)
156 for (head
= arch
->next
; head
; head
= head
->next
)
164 /* This may appear to be a baroque way of accomplishing what we want.
165 However we have to iterate over the filenames in order to notice where
166 a filename is requested but does not exist in the archive. Ditto
167 mapping over each file each time -- we want to hack multiple
170 for (; count
> 0; files
++, count
--)
172 bfd_boolean found
= FALSE
;
175 for (head
= arch
->next
; head
; head
= head
->next
)
178 if (head
->filename
== NULL
)
180 /* Some archive formats don't get the filenames filled in
181 until the elements are opened. */
183 bfd_stat_arch_elt (head
, &buf
);
185 if ((head
->filename
!= NULL
) &&
186 (!FILENAME_CMP (normalize (*files
, arch
), head
->filename
)))
189 if (counted_name_mode
190 && match_count
!= counted_name_counter
)
192 /* Counting, and didn't match on count; go on to the
202 /* xgettext:c-format */
203 fprintf (stderr
, _("no entry %s in archive\n"), *files
);
207 bfd_boolean operation_alters_arch
= FALSE
;
214 s
= help
? stdout
: stderr
;
218 /* xgettext:c-format */
219 fprintf (s
, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
221 /* xgettext:c-format */
222 fprintf (s
, _(" %s -M [<mri-script]\n"), program_name
);
223 fprintf (s
, _(" commands:\n"));
224 fprintf (s
, _(" d - delete file(s) from the archive\n"));
225 fprintf (s
, _(" m[ab] - move file(s) in the archive\n"));
226 fprintf (s
, _(" p - print file(s) found in the archive\n"));
227 fprintf (s
, _(" q[f] - quick append file(s) to the archive\n"));
228 fprintf (s
, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
229 fprintf (s
, _(" t - display contents of archive\n"));
230 fprintf (s
, _(" x[o] - extract file(s) from the archive\n"));
231 fprintf (s
, _(" command specific modifiers:\n"));
232 fprintf (s
, _(" [a] - put file(s) after [member-name]\n"));
233 fprintf (s
, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
234 fprintf (s
, _(" [N] - use instance [count] of name\n"));
235 fprintf (s
, _(" [f] - truncate inserted file names\n"));
236 fprintf (s
, _(" [P] - use full path names when matching\n"));
237 fprintf (s
, _(" [o] - preserve original dates\n"));
238 fprintf (s
, _(" [u] - only replace files that are newer than current archive contents\n"));
239 fprintf (s
, _(" generic modifiers:\n"));
240 fprintf (s
, _(" [c] - do not warn if the library had to be created\n"));
241 fprintf (s
, _(" [s] - create an archive index (cf. ranlib)\n"));
242 fprintf (s
, _(" [S] - do not build a symbol table\n"));
243 fprintf (s
, _(" [v] - be verbose\n"));
244 fprintf (s
, _(" [V] - display the version number\n"));
245 fprintf (s
, _(" @<file> - read options from <file>\n"));
251 /* xgettext:c-format */
252 fprintf (s
, _("Usage: %s [options] archive\n"), program_name
);
253 fprintf (s
, _(" Generate an index to speed access to archives\n"));
254 fprintf (s
, _(" The options are:\n\
255 @<file> Read options from <file>\n\
256 -h --help Print this help message\n\
257 -V --version Print version information\n"));
260 list_supported_targets (program_name
, stderr
);
263 fprintf (s
, _("Report bugs to %s\n"), REPORT_BUGS_TO
);
265 xexit (help
? 0 : 1);
268 /* Normalize a file name specified on the command line into a file
269 name which we will use in an archive. */
272 normalize (const char *file
, bfd
*abfd
)
274 const char *filename
;
279 filename
= strrchr (file
, '/');
280 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
282 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
283 char *bslash
= strrchr (file
, '\\');
284 if (filename
== NULL
|| (bslash
!= NULL
&& bslash
> filename
))
286 if (filename
== NULL
&& file
[0] != '\0' && file
[1] == ':')
290 if (filename
!= (char *) NULL
)
297 && strlen (filename
) > abfd
->xvec
->ar_max_namelen
)
302 s
= (char *) xmalloc (abfd
->xvec
->ar_max_namelen
+ 1);
303 memcpy (s
, filename
, abfd
->xvec
->ar_max_namelen
);
304 s
[abfd
->xvec
->ar_max_namelen
] = '\0';
311 /* Remove any output file. This is only called via xatexit. */
313 static const char *output_filename
= NULL
;
314 static FILE *output_file
= NULL
;
315 static bfd
*output_bfd
= NULL
;
320 if (output_filename
!= NULL
)
322 if (output_bfd
!= NULL
)
323 bfd_cache_close (output_bfd
);
324 if (output_file
!= NULL
)
325 fclose (output_file
);
326 unlink_if_ordinary (output_filename
);
330 /* The option parsing should be in its own function.
331 It will be when I have getopt working. */
333 int main (int, char **);
336 main (int argc
, char **argv
)
342 none
= 0, delete, replace
, print_table
,
343 print_files
, extract
, move
, quick_append
348 char *inarch_filename
;
353 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
354 setlocale (LC_MESSAGES
, "");
356 #if defined (HAVE_SETLOCALE)
357 setlocale (LC_CTYPE
, "");
359 bindtextdomain (PACKAGE
, LOCALEDIR
);
360 textdomain (PACKAGE
);
362 program_name
= argv
[0];
363 xmalloc_set_program_name (program_name
);
365 expandargv (&argc
, &argv
);
371 temp
= strrchr (program_name
, '/');
372 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
374 /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
375 char *bslash
= strrchr (program_name
, '\\');
376 if (temp
== NULL
|| (bslash
!= NULL
&& bslash
> temp
))
378 if (temp
== NULL
&& program_name
[0] != '\0' && program_name
[1] == ':')
379 temp
= program_name
+ 1;
386 if (strlen (temp
) >= 6
387 && FILENAME_CMP (temp
+ strlen (temp
) - 6, "ranlib") == 0)
393 if (argc
> 1 && argv
[1][0] == '-')
395 if (strcmp (argv
[1], "--help") == 0)
397 else if (strcmp (argv
[1], "--version") == 0)
400 print_version ("ranlib");
402 print_version ("ar");
406 START_PROGRESS (program_name
, 0);
409 set_default_bfd_target ();
413 xatexit (remove_output
);
415 for (i
= 1; i
< argc
; i
++)
416 if (! ar_emul_parse_arg (argv
[i
]))
423 bfd_boolean touch
= FALSE
;
426 || strcmp (argv
[1], "--help") == 0
427 || strcmp (argv
[1], "-h") == 0
428 || strcmp (argv
[1], "-H") == 0)
430 if (strcmp (argv
[1], "-V") == 0
431 || strcmp (argv
[1], "-v") == 0
432 || strncmp (argv
[1], "--v", 3) == 0)
433 print_version ("ranlib");
435 if (strcmp (argv
[1], "-t") == 0)
440 while (arg_index
< argc
)
443 ranlib_only (argv
[arg_index
]);
445 ranlib_touch (argv
[arg_index
]);
451 if (argc
== 2 && strcmp (argv
[1], "-M") == 0)
461 arg_ptr
= argv
[arg_index
];
465 /* When the first option starts with '-' we support POSIX-compatible
468 ++arg_ptr
; /* compatibility */
473 while ((c
= *arg_ptr
++) != '\0')
484 if (operation
!= none
)
485 fatal (_("two different operation options specified"));
490 operation_alters_arch
= TRUE
;
494 operation_alters_arch
= TRUE
;
497 operation
= print_files
;
500 operation
= quick_append
;
501 operation_alters_arch
= TRUE
;
505 operation_alters_arch
= TRUE
;
508 operation
= print_table
;
541 postype
= pos_before
;
544 postype
= pos_before
;
550 counted_name_mode
= TRUE
;
556 full_pathname
= TRUE
;
559 /* xgettext:c-format */
560 non_fatal (_("illegal option -- %c"), c
);
565 /* With POSIX-compatible option parsing continue with the next
566 argument if it starts with '-'. */
567 if (do_posix
&& arg_index
+ 1 < argc
&& argv
[arg_index
+ 1][0] == '-')
568 arg_ptr
= argv
[++arg_index
] + 1;
575 print_version ("ar");
578 if (arg_index
>= argc
)
589 /* We don't use do_quick_append any more. Too many systems
590 expect ar to always rebuild the symbol table even when q is
593 /* We can't write an armap when using ar q, so just do ar r
595 if (operation
== quick_append
&& write_armap
)
598 if ((operation
== none
|| operation
== print_table
)
601 ranlib_only (argv
[arg_index
]);
605 if (operation
== none
)
606 fatal (_("no operation specified"));
608 if (newer_only
&& operation
!= replace
)
609 fatal (_("`u' is only meaningful with the `r' option."));
611 if (postype
!= pos_default
)
612 posname
= argv
[arg_index
++];
614 if (counted_name_mode
)
616 if (operation
!= extract
&& operation
!= delete)
617 fatal (_("`N' is only meaningful with the `x' and `d' options."));
618 counted_name_counter
= atoi (argv
[arg_index
++]);
619 if (counted_name_counter
<= 0)
620 fatal (_("Value for `N' must be positive."));
623 inarch_filename
= argv
[arg_index
++];
625 files
= arg_index
< argc
? argv
+ arg_index
: NULL
;
626 file_count
= argc
- arg_index
;
628 arch
= open_inarch (inarch_filename
,
629 files
== NULL
? (char *) NULL
: files
[0]);
634 map_over_members (arch
, print_descr
, files
, file_count
);
638 map_over_members (arch
, print_contents
, files
, file_count
);
642 map_over_members (arch
, extract_file
, files
, file_count
);
647 delete_members (arch
, files
);
649 output_filename
= NULL
;
654 move_members (arch
, files
);
656 output_filename
= NULL
;
661 if (files
!= NULL
|| write_armap
> 0)
662 replace_members (arch
, files
, operation
== quick_append
);
664 output_filename
= NULL
;
667 /* Shouldn't happen! */
669 /* xgettext:c-format */
670 fatal (_("internal error -- this option not implemented"));
674 END_PROGRESS (program_name
);
681 open_inarch (const char *archive_filename
, const char *file
)
690 bfd_set_error (bfd_error_no_error
);
694 if (stat (archive_filename
, &sbuf
) != 0)
696 #if !defined(__GO32__) || defined(__DJGPP__)
698 /* FIXME: I don't understand why this fragment was ifndef'ed
699 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
700 stat() works just fine in v2.x, so I think this should be
701 removed. For now, I enable it for DJGPP v2. -- EZ. */
703 /* KLUDGE ALERT! Temporary fix until I figger why
704 stat() is wrong ... think it's buried in GO32's IDT - Jax */
706 bfd_fatal (archive_filename
);
709 if (!operation_alters_arch
)
711 fprintf (stderr
, "%s: ", program_name
);
712 perror (archive_filename
);
717 /* Try to figure out the target to use for the archive from the
718 first object on the list. */
723 obj
= bfd_openr (file
, NULL
);
726 if (bfd_check_format (obj
, bfd_object
))
727 target
= bfd_get_target (obj
);
728 (void) bfd_close (obj
);
732 /* Create an empty archive. */
733 arch
= bfd_openw (archive_filename
, target
);
735 || ! bfd_set_format (arch
, bfd_archive
)
736 || ! bfd_close (arch
))
737 bfd_fatal (archive_filename
);
738 else if (!silent_create
)
739 non_fatal (_("creating %s"), archive_filename
);
741 /* If we die creating a new archive, don't leave it around. */
742 output_filename
= archive_filename
;
745 arch
= bfd_openr (archive_filename
, target
);
749 bfd_fatal (archive_filename
);
752 if (! bfd_check_format_matches (arch
, bfd_archive
, &matching
))
754 bfd_nonfatal (archive_filename
);
755 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
757 list_matching_formats (matching
);
763 last_one
= &(arch
->next
);
764 /* Read all the contents right away, regardless. */
765 for (next_one
= bfd_openr_next_archived_file (arch
, NULL
);
767 next_one
= bfd_openr_next_archived_file (arch
, next_one
))
770 *last_one
= next_one
;
771 last_one
= &next_one
->next
;
773 *last_one
= (bfd
*) NULL
;
774 if (bfd_get_error () != bfd_error_no_more_archived_files
)
780 print_contents (bfd
*abfd
)
783 char *cbuf
= xmalloc (BUFSIZE
);
786 if (bfd_stat_arch_elt (abfd
, &buf
) != 0)
787 /* xgettext:c-format */
788 fatal (_("internal stat error on %s"), bfd_get_filename (abfd
));
791 /* xgettext:c-format */
792 printf (_("\n<%s>\n\n"), bfd_get_filename (abfd
));
794 bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
);
797 while (ncopied
< size
)
801 int tocopy
= size
- ncopied
;
802 if (tocopy
> BUFSIZE
)
805 nread
= bfd_bread (cbuf
, (bfd_size_type
) tocopy
, abfd
);
807 /* xgettext:c-format */
808 fatal (_("%s is not a valid archive"),
809 bfd_get_filename (bfd_my_archive (abfd
)));
810 fwrite (cbuf
, 1, nread
, stdout
);
816 /* Extract a member of the archive into its own file.
818 We defer opening the new file until after we have read a BUFSIZ chunk of the
819 old one, since we know we have just read the archive header for the old
820 one. Since most members are shorter than BUFSIZ, this means we will read
821 the old header, read the old data, write a new inode for the new file, and
822 write the new data, and be done. This 'optimization' is what comes from
823 sitting next to a bare disk and hearing it every time it seeks. -- Gnu
827 extract_file (bfd
*abfd
)
830 char *cbuf
= xmalloc (BUFSIZE
);
836 if (bfd_stat_arch_elt (abfd
, &buf
) != 0)
837 /* xgettext:c-format */
838 fatal (_("internal stat error on %s"), bfd_get_filename (abfd
));
842 /* xgettext:c-format */
843 fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd
));
846 printf ("x - %s\n", bfd_get_filename (abfd
));
848 bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
);
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
);
859 perror (bfd_get_filename (abfd
));
863 output_file
= ostream
;
866 while (ncopied
< size
)
868 tocopy
= size
- ncopied
;
869 if (tocopy
> BUFSIZE
)
872 nread
= bfd_bread (cbuf
, (bfd_size_type
) tocopy
, abfd
);
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 */
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
);
887 perror (bfd_get_filename (abfd
));
891 output_file
= ostream
;
893 fwrite (cbuf
, 1, nread
, ostream
);
901 output_filename
= NULL
;
903 chmod (bfd_get_filename (abfd
), buf
.st_mode
);
907 /* Set access time to modification time. Only st_mtime is
908 initialized by bfd_stat_arch_elt. */
909 buf
.st_atime
= buf
.st_mtime
;
910 set_times (bfd_get_filename (abfd
), &buf
);
917 write_archive (bfd
*iarch
)
920 char *old_name
, *new_name
;
921 bfd
*contents_head
= iarch
->next
;
923 old_name
= xmalloc (strlen (bfd_get_filename (iarch
)) + 1);
924 strcpy (old_name
, bfd_get_filename (iarch
));
925 new_name
= make_tempname (old_name
);
927 output_filename
= new_name
;
929 obfd
= bfd_openw (new_name
, bfd_get_target (iarch
));
932 bfd_fatal (old_name
);
936 bfd_set_format (obfd
, bfd_archive
);
938 /* Request writing the archive symbol table unless we've
939 been explicitly requested not to. */
940 obfd
->has_armap
= write_armap
>= 0;
944 /* This should really use bfd_set_file_flags, but that rejects
946 obfd
->flags
|= BFD_TRADITIONAL_FORMAT
;
949 if (!bfd_set_archive_head (obfd
, contents_head
))
950 bfd_fatal (old_name
);
952 if (!bfd_close (obfd
))
953 bfd_fatal (old_name
);
956 output_filename
= NULL
;
958 /* We don't care if this fails; we might be creating the archive. */
961 if (smart_rename (new_name
, old_name
, 0) != 0)
965 /* Return a pointer to the pointer to the entry which should be rplacd'd
966 into when altering. DEFAULT_POS should be how to interpret pos_default,
967 and should be a pos value. */
970 get_pos_bfd (bfd
**contents
, enum pos default_pos
, const char *default_posname
)
972 bfd
**after_bfd
= contents
;
974 const char *realposname
;
976 if (postype
== pos_default
)
978 realpos
= default_pos
;
979 realposname
= default_posname
;
984 realposname
= posname
;
987 if (realpos
== pos_end
)
990 after_bfd
= &((*after_bfd
)->next
);
994 for (; *after_bfd
; after_bfd
= &(*after_bfd
)->next
)
995 if (FILENAME_CMP ((*after_bfd
)->filename
, realposname
) == 0)
997 if (realpos
== pos_after
)
998 after_bfd
= &(*after_bfd
)->next
;
1006 delete_members (bfd
*arch
, char **files_to_delete
)
1008 bfd
**current_ptr_ptr
;
1010 bfd_boolean something_changed
= FALSE
;
1013 for (; *files_to_delete
!= NULL
; ++files_to_delete
)
1015 /* In a.out systems, the armap is optional. It's also called
1016 __.SYMDEF. So if the user asked to delete it, we should remember
1017 that fact. This isn't quite right for COFF systems (where
1018 __.SYMDEF might be regular member), but it's very unlikely
1019 to be a problem. FIXME */
1021 if (!strcmp (*files_to_delete
, "__.SYMDEF"))
1023 arch
->has_armap
= FALSE
;
1030 current_ptr_ptr
= &(arch
->next
);
1031 while (*current_ptr_ptr
)
1033 if (FILENAME_CMP (normalize (*files_to_delete
, arch
),
1034 (*current_ptr_ptr
)->filename
) == 0)
1037 if (counted_name_mode
1038 && match_count
!= counted_name_counter
)
1040 /* Counting, and didn't match on count; go on to the
1046 something_changed
= TRUE
;
1050 *current_ptr_ptr
= ((*current_ptr_ptr
)->next
);
1055 current_ptr_ptr
= &((*current_ptr_ptr
)->next
);
1058 if (verbose
&& !found
)
1060 /* xgettext:c-format */
1061 printf (_("No member named `%s'\n"), *files_to_delete
);
1067 if (something_changed
)
1068 write_archive (arch
);
1070 output_filename
= NULL
;
1074 /* Reposition existing members within an archive */
1077 move_members (bfd
*arch
, char **files_to_move
)
1079 bfd
**after_bfd
; /* New entries go after this one */
1080 bfd
**current_ptr_ptr
; /* cdr pointer into contents */
1082 for (; *files_to_move
; ++files_to_move
)
1084 current_ptr_ptr
= &(arch
->next
);
1085 while (*current_ptr_ptr
)
1087 bfd
*current_ptr
= *current_ptr_ptr
;
1088 if (FILENAME_CMP (normalize (*files_to_move
, arch
),
1089 current_ptr
->filename
) == 0)
1091 /* Move this file to the end of the list - first cut from
1094 *current_ptr_ptr
= current_ptr
->next
;
1096 /* Now glue to end */
1097 after_bfd
= get_pos_bfd (&arch
->next
, pos_end
, NULL
);
1099 *after_bfd
= current_ptr
;
1100 current_ptr
->next
= link
;
1103 printf ("m - %s\n", *files_to_move
);
1108 current_ptr_ptr
= &((*current_ptr_ptr
)->next
);
1110 /* xgettext:c-format */
1111 fatal (_("no entry %s in archive %s!"), *files_to_move
, arch
->filename
);
1116 write_archive (arch
);
1119 /* Ought to default to replacing in place, but this is existing practice! */
1122 replace_members (bfd
*arch
, char **files_to_move
, bfd_boolean quick
)
1124 bfd_boolean changed
= FALSE
;
1125 bfd
**after_bfd
; /* New entries go after this one. */
1129 while (files_to_move
&& *files_to_move
)
1133 current_ptr
= &arch
->next
;
1134 while (*current_ptr
)
1136 current
= *current_ptr
;
1138 /* For compatibility with existing ar programs, we
1139 permit the same file to be added multiple times. */
1140 if (FILENAME_CMP (normalize (*files_to_move
, arch
),
1141 normalize (current
->filename
, arch
)) == 0
1142 && current
->arelt_data
!= NULL
)
1146 struct stat fsbuf
, asbuf
;
1148 if (stat (*files_to_move
, &fsbuf
) != 0)
1150 if (errno
!= ENOENT
)
1151 bfd_fatal (*files_to_move
);
1154 if (bfd_stat_arch_elt (current
, &asbuf
) != 0)
1155 /* xgettext:c-format */
1156 fatal (_("internal stat error on %s"),
1159 if (fsbuf
.st_mtime
<= asbuf
.st_mtime
)
1163 after_bfd
= get_pos_bfd (&arch
->next
, pos_after
,
1165 if (ar_emul_replace (after_bfd
, *files_to_move
,
1168 /* Snip out this entry from the chain. */
1169 *current_ptr
= (*current_ptr
)->next
;
1175 current_ptr
= &(current
->next
);
1179 /* Add to the end of the archive. */
1180 after_bfd
= get_pos_bfd (&arch
->next
, pos_end
, NULL
);
1182 if (ar_emul_append (after_bfd
, *files_to_move
, verbose
))
1191 write_archive (arch
);
1193 output_filename
= NULL
;
1197 ranlib_only (const char *archname
)
1201 if (get_file_size (archname
) < 1)
1204 arch
= open_inarch (archname
, (char *) NULL
);
1207 write_archive (arch
);
1210 /* Update the timestamp of the symbol map of an archive. */
1213 ranlib_touch (const char *archname
)
1216 /* I don't think updating works on go32. */
1217 ranlib_only (archname
);
1223 if (get_file_size (archname
) < 1)
1225 f
= open (archname
, O_RDWR
| O_BINARY
, 0);
1228 bfd_set_error (bfd_error_system_call
);
1229 bfd_fatal (archname
);
1232 arch
= bfd_fdopenr (archname
, (const char *) NULL
, f
);
1234 bfd_fatal (archname
);
1235 if (! bfd_check_format_matches (arch
, bfd_archive
, &matching
))
1237 bfd_nonfatal (archname
);
1238 if (bfd_get_error () == bfd_error_file_ambiguously_recognized
)
1240 list_matching_formats (matching
);
1246 if (! bfd_has_map (arch
))
1247 /* xgettext:c-format */
1248 fatal (_("%s: no archive map to update"), archname
);
1250 bfd_update_armap_timestamp (arch
);
1252 if (! bfd_close (arch
))
1253 bfd_fatal (archname
);
1257 /* Things which are interesting to map over all or some of the files: */
1260 print_descr (bfd
*abfd
)
1262 print_arelt_descr (stdout
, abfd
, verbose
);