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
28 #include "libiberty.h"
36 #ifdef HAVE_GOOD_UTIME_H
38 #else /* ! HAVE_GOOD_UTIME_H */
41 #endif /* HAVE_UTIMES */
42 #endif /* ! HAVE_GOOD_UTIME_H */
45 #define EXT_NAME_LEN 3 /* bufflen of addition to name if it's MS-DOS */
47 #define EXT_NAME_LEN 6 /* ditto for *NIX */
52 /* Kludge declaration from BFD! This is ugly! FIXME! XXX */
55 bfd_special_undocumented_glue
PARAMS ((bfd
* abfd
, char *filename
));
57 /* Forward declarations */
60 normalize
PARAMS ((const char *, bfd
*));
63 remove_output
PARAMS ((void));
66 map_over_members
PARAMS ((bfd
*, void (*)(bfd
*), char **, int));
69 print_contents
PARAMS ((bfd
* member
));
72 delete_members
PARAMS ((bfd
*, char **files_to_delete
));
76 do_quick_append
PARAMS ((const char *archive_filename
,
77 char **files_to_append
));
81 move_members
PARAMS ((bfd
*, char **files_to_move
));
84 replace_members
PARAMS ((bfd
*, char **files_to_replace
, boolean quick
));
87 print_descr
PARAMS ((bfd
* abfd
));
90 write_archive
PARAMS ((bfd
*));
93 ranlib_only
PARAMS ((const char *archname
));
96 ranlib_touch
PARAMS ((const char *archname
));
98 /** Globals and flags */
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. */
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. */
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;
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. */
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. */
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;
150 interactive
= isatty (fileno (stdin
));
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. */
159 map_over_members (arch
, function
, files
, count
)
161 void (*function
) PARAMS ((bfd
*));
169 for (head
= arch
->next
; head
; head
= head
->next
)
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
182 for (; count
> 0; files
++, count
--)
184 boolean found
= false;
186 for (head
= arch
->next
; head
; head
= head
->next
)
189 if (head
->filename
== NULL
)
191 /* Some archive formats don't get the filenames filled in
192 until the elements are opened. */
194 bfd_stat_arch_elt (head
, &buf
);
196 if ((head
->filename
!= NULL
) &&
197 (!strcmp (*files
, head
->filename
)))
204 fprintf (stderr
, "no entry %s in archive\n", *files
);
208 boolean operation_alters_arch
= false;
216 s
= help
? stdout
: stderr
;
219 Usage: %s [-]{dmpqrtx}[abcilosuvV] [member-name] archive-file file...\n\
220 %s -M [<mri-script]\n",
221 program_name
, program_name
);
224 Usage: %s [-vV] archive\n", program_name
);
226 list_supported_targets (program_name
, stderr
);
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. */
238 normalize (file
, abfd
)
242 const char *filename
;
244 filename
= strrchr (file
, '/');
245 if (filename
!= (char *) NULL
)
252 && strlen (filename
) > abfd
->xvec
->ar_max_namelen
)
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';
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
;
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. */
297 none
= 0, delete, replace
, print_table
,
298 print_files
, extract
, move
, quick_append
302 char *inarch_filename
;
305 program_name
= argv
[0];
306 xmalloc_set_program_name (program_name
);
312 temp
= strrchr (program_name
, '/');
317 if (strlen (temp
) >= 6
318 && strcmp (temp
+ strlen (temp
) - 6, "ranlib") == 0)
324 if (argc
> 1 && argv
[1][0] == '-')
326 if (strcmp (argv
[1], "--help") == 0)
328 else if (strcmp (argv
[1], "--version") == 0)
331 print_version ("ranlib");
333 print_version ("ar");
337 START_PROGRESS (program_name
, 0);
342 xatexit (remove_output
);
346 boolean touch
= false;
348 if (argc
< 2 || strcmp (argv
[1], "--help") == 0)
350 if (strcmp (argv
[1], "-V") == 0
351 || strcmp (argv
[1], "-v") == 0
352 || strncmp (argv
[1], "--v", 3) == 0)
353 print_version ("ranlib");
355 if (strcmp (argv
[1], "-t") == 0)
360 while (arg_index
< argc
)
363 ranlib_only (argv
[arg_index
]);
365 ranlib_touch (argv
[arg_index
]);
371 if (argc
== 2 && strcmp (argv
[1], "-M") == 0)
383 ++arg_ptr
; /* compatibility */
385 while ((c
= *arg_ptr
++) != '\0')
396 if (operation
!= none
)
397 fatal ("two different operation options specified");
402 operation_alters_arch
= true;
406 operation_alters_arch
= true;
409 operation
= print_files
;
412 operation
= quick_append
;
413 operation_alters_arch
= true;
417 operation_alters_arch
= true;
420 operation
= print_table
;
450 postype
= pos_before
;
453 postype
= pos_before
;
462 fprintf (stderr
, "%s: illegal option -- %c\n", program_name
, c
);
468 print_version ("ar");
481 /* We can't write an armap when using ar q, so just do ar r
483 if (operation
== quick_append
&& write_armap
)
486 if ((operation
== none
|| operation
== print_table
)
489 ranlib_only (argv
[2]);
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.");
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
;
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
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
)
522 for (chk
= files
; chk
!= NULL
&& *chk
!= '\0'; chk
++)
524 if (strlen (normalize (*chk
, (bfd
*) NULL
)) > 14)
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
);
541 arch
= open_inarch (inarch_filename
,
542 files
== NULL
? (char *) NULL
: files
[0]);
547 map_over_members (arch
, print_descr
, files
, argc
- 3);
551 map_over_members (arch
, print_contents
, files
, argc
- 3);
555 map_over_members (arch
, extract_file
, files
, argc
- 3);
560 delete_members (arch
, files
);
565 move_members (arch
, files
);
570 if (files
!= NULL
|| write_armap
> 0)
571 replace_members (arch
, files
, operation
== quick_append
);
574 /* Shouldn't happen! */
576 fprintf (stderr
, "%s: internal error -- this option not implemented\n",
582 END_PROGRESS (program_name
);
589 open_inarch (archive_filename
, file
)
590 const char *archive_filename
;
600 bfd_set_error (bfd_error_no_error
);
604 if (stat (archive_filename
, &sbuf
) != 0)
610 /* KLUDGE ALERT! Temporary fix until I figger why
611 * stat() is wrong ... think it's buried in GO32's IDT
615 bfd_fatal (archive_filename
);
618 if (!operation_alters_arch
)
620 fprintf (stderr
, "%s: ", program_name
);
621 perror (archive_filename
);
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
);
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
);
639 || ! bfd_set_format (arch
, bfd_archive
)
640 || ! bfd_close (arch
))
641 bfd_fatal (archive_filename
);
644 arch
= bfd_openr (archive_filename
, target
);
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
);
662 last_one
= &(arch
->next
);
663 /* Read all the contents right away, regardless. */
664 for (next_one
= bfd_openr_next_archived_file (arch
, NULL
);
666 next_one
= bfd_openr_next_archived_file (arch
, next_one
))
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
)
679 print_contents (abfd
)
683 char *cbuf
= xmalloc (BUFSIZE
);
686 if (bfd_stat_arch_elt (abfd
, &buf
) != 0)
687 fatal ("internal stat error on %s", bfd_get_filename (abfd
));
690 printf ("\n<member %s>\n\n", bfd_get_filename (abfd
));
692 bfd_seek (abfd
, 0, SEEK_SET
);
695 while (ncopied
< size
)
699 int tocopy
= size
- ncopied
;
700 if (tocopy
> BUFSIZE
)
703 nread
= bfd_read (cbuf
, 1, tocopy
, abfd
); /* oops -- broke
706 fatal ("%s is not a valid archive",
707 bfd_get_filename (bfd_my_archive (abfd
)));
708 fwrite (cbuf
, 1, nread
, stdout
);
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
729 char *cbuf
= xmalloc (BUFSIZE
);
734 if (bfd_stat_arch_elt (abfd
, &buf
) != 0)
735 fatal ("internal stat error on %s", bfd_get_filename (abfd
));
739 printf ("x - %s\n", bfd_get_filename (abfd
));
741 bfd_seek (abfd
, 0, SEEK_SET
);
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
);
752 perror (bfd_get_filename (abfd
));
756 output_file
= ostream
;
759 while (ncopied
< size
)
761 tocopy
= size
- ncopied
;
762 if (tocopy
> BUFSIZE
)
765 nread
= bfd_read (cbuf
, 1, tocopy
, abfd
);
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 */
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
);
779 perror (bfd_get_filename (abfd
));
783 output_file
= ostream
;
785 fwrite (cbuf
, 1, nread
, ostream
);
792 output_filename
= NULL
;
794 chmod (bfd_get_filename (abfd
), buf
.st_mode
);
798 #ifdef HAVE_GOOD_UTIME_H
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 */
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
;
813 tv
[1].tv_sec
= buf
.st_mtime
;
815 utimes (bfd_get_filename (abfd
), tv
); /* FIXME check result */
816 #endif /* HAVE_UTIMES */
817 #endif /* ! HAVE_GOOD_UTIME_H */
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 */
830 do_quick_append (archive_filename
, files_to_append
)
831 const char *archive_filename
;
832 char **files_to_append
;
835 char *buf
= xmalloc (BUFSIZE
);
836 long tocopy
, thistime
;
839 boolean newfile
= false;
840 bfd_set_error (bfd_error_no_error
);
842 if (stat (archive_filename
, &sbuf
) != 0)
847 /* KLUDGE ALERT! Temporary fix until I figger why
848 * stat() is wrong ... think it's buried in GO32's IDT
853 bfd_fatal (archive_filename
);
859 ofile
= fopen (archive_filename
, FOPEN_AUB
);
862 perror (program_name
);
866 temp
= bfd_openr (archive_filename
, 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
);
878 fwrite (ARMAG
, 1, SARMAG
, ofile
);
880 fprintf (stderr
, "%s: creating %s\n",
881 program_name
, archive_filename
);
885 temp
->flags
|= BFD_TRADITIONAL_FORMAT
;
887 /* assume it's an achive, go straight to the end, sans $200 */
890 for (; files_to_append
&& *files_to_append
; ++files_to_append
)
892 struct ar_hdr
*hdr
= bfd_special_undocumented_glue (temp
, *files_to_append
);
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
);
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
);
919 if (thistime
> BUFSIZE
)
921 fread (buf
, 1, thistime
, ifile
);
922 fwrite (buf
, 1, thistime
, ofile
);
926 if ((sbuf
.st_size
% 2) == 1)
927 putc ('\012', ofile
);
937 write_archive (iarch
)
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
));
953 bfd_fatal (old_name
);
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;
965 /* This should really use bfd_set_file_flags, but that rejects
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
);
977 output_filename
= NULL
;
979 /* We don't care if this fails; we might be creating the archive. */
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. */
992 get_pos_bfd (contents
, default_pos
)
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
)
1002 after_bfd
= &((*after_bfd
)->next
);
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
;
1018 delete_members (arch
, files_to_delete
)
1020 char **files_to_delete
;
1022 bfd
**current_ptr_ptr
;
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;
1041 current_ptr_ptr
= &(arch
->next
);
1042 while (*current_ptr_ptr
)
1044 if (strcmp (*files_to_delete
, (*current_ptr_ptr
)->filename
) == 0)
1047 something_changed
= true;
1051 *current_ptr_ptr
= ((*current_ptr_ptr
)->next
);
1056 current_ptr_ptr
= &((*current_ptr_ptr
)->next
);
1060 if (verbose
&& found
== false)
1062 printf ("No member named `%s'\n", *files_to_delete
);
1068 if (something_changed
== true)
1070 write_archive (arch
);
1075 /* Reposition existing members within an archive */
1078 move_members (arch
, files_to_move
)
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
1097 *current_ptr_ptr
= current_ptr
->next
;
1099 /* Now glue to end */
1100 after_bfd
= get_pos_bfd (&arch
->next
, pos_end
);
1102 *after_bfd
= current_ptr
;
1103 current_ptr
->next
= link
;
1106 printf ("m - %s\n", *files_to_move
);
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
);
1119 write_archive (arch
);
1122 /* Ought to default to replacing in place, but this is existing practice! */
1125 replace_members (arch
, files_to_move
, quick
)
1127 char **files_to_move
;
1130 boolean changed
= false;
1131 bfd
**after_bfd
; /* New entries go after this one */
1136 while (files_to_move
&& *files_to_move
)
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
)
1153 struct stat fsbuf
, asbuf
;
1155 if (stat (*files_to_move
, &fsbuf
) != 0)
1157 if (errno
!= ENOENT
)
1158 bfd_fatal (*files_to_move
);
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
)
1168 /* snip out this entry from the chain */
1169 *current_ptr
= current
->next
;
1171 after_bfd
= get_pos_bfd (&arch
->next
, pos_end
);
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
;
1182 printf ("r - %s\n", *files_to_move
);
1189 current_ptr
= &(current
->next
);
1193 /* Add to the end of the archive. */
1195 after_bfd
= get_pos_bfd (&arch
->next
, pos_end
);
1197 *after_bfd
= bfd_openr (*files_to_move
, NULL
);
1198 if (*after_bfd
== (bfd
*) NULL
)
1200 bfd_fatal (*files_to_move
);
1204 printf ("a - %s\n", *files_to_move
);
1207 (*after_bfd
)->next
= temp
;
1217 write_archive (arch
);
1221 ranlib_only (archname
)
1222 const char *archname
;
1227 arch
= open_inarch (archname
, (char *) NULL
);
1230 write_archive (arch
);
1233 /* Update the timestamp of the symbol map of an archive. */
1236 ranlib_touch (archname
)
1237 const char *archname
;
1240 /* I don't think updating works on go32. */
1241 ranlib_only (archname
);
1247 f
= open (archname
, O_RDWR
, 0);
1250 bfd_set_error (bfd_error_system_call
);
1251 bfd_fatal (archname
);
1254 arch
= bfd_fdopenr (archname
, (const char *) NULL
, f
);
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
);
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
);
1278 /* Things which are interesting to map over all or some of the files: */
1284 print_arelt_descr (stdout
, abfd
, verbose
);