1*fae548d3Szrj /* ar.c - Archive modify and extract.
2*fae548d3Szrj Copyright (C) 1991-2020 Free Software Foundation, Inc.
3*fae548d3Szrj
4*fae548d3Szrj This file is part of GNU Binutils.
5*fae548d3Szrj
6*fae548d3Szrj This program is free software; you can redistribute it and/or modify
7*fae548d3Szrj it under the terms of the GNU General Public License as published by
8*fae548d3Szrj the Free Software Foundation; either version 3 of the License, or
9*fae548d3Szrj (at your option) any later version.
10*fae548d3Szrj
11*fae548d3Szrj This program is distributed in the hope that it will be useful,
12*fae548d3Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
13*fae548d3Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*fae548d3Szrj GNU General Public License for more details.
15*fae548d3Szrj
16*fae548d3Szrj You should have received a copy of the GNU General Public License
17*fae548d3Szrj along with this program; if not, write to the Free Software
18*fae548d3Szrj Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19*fae548d3Szrj MA 02110-1301, USA. */
20*fae548d3Szrj
21*fae548d3Szrj /*
22*fae548d3Szrj Bugs: GNU ar used to check file against filesystem in quick_update and
23*fae548d3Szrj replace operations (would check mtime). Doesn't warn when name truncated.
24*fae548d3Szrj No way to specify pos_end. Error messages should be more consistent. */
25*fae548d3Szrj
26*fae548d3Szrj #include "sysdep.h"
27*fae548d3Szrj #include "bfd.h"
28*fae548d3Szrj #include "libiberty.h"
29*fae548d3Szrj #include "progress.h"
30*fae548d3Szrj #include "getopt.h"
31*fae548d3Szrj #include "aout/ar.h"
32*fae548d3Szrj #include "bucomm.h"
33*fae548d3Szrj #include "arsup.h"
34*fae548d3Szrj #include "filenames.h"
35*fae548d3Szrj #include "binemul.h"
36*fae548d3Szrj #include "plugin-api.h"
37*fae548d3Szrj #include "plugin.h"
38*fae548d3Szrj #include "ansidecl.h"
39*fae548d3Szrj
40*fae548d3Szrj #ifdef __GO32___
41*fae548d3Szrj #define EXT_NAME_LEN 3 /* Bufflen of addition to name if it's MS-DOS. */
42*fae548d3Szrj #else
43*fae548d3Szrj #define EXT_NAME_LEN 6 /* Ditto for *NIX. */
44*fae548d3Szrj #endif
45*fae548d3Szrj
46*fae548d3Szrj /* Static declarations. */
47*fae548d3Szrj
48*fae548d3Szrj static void mri_emul (void);
49*fae548d3Szrj static const char *normalize (const char *, bfd *);
50*fae548d3Szrj static void remove_output (void);
51*fae548d3Szrj static void map_over_members (bfd *, void (*)(bfd *), char **, int);
52*fae548d3Szrj static void print_contents (bfd * member);
53*fae548d3Szrj static void delete_members (bfd *, char **files_to_delete);
54*fae548d3Szrj
55*fae548d3Szrj static void move_members (bfd *, char **files_to_move);
56*fae548d3Szrj static void replace_members
57*fae548d3Szrj (bfd *, char **files_to_replace, bfd_boolean quick);
58*fae548d3Szrj static void print_descr (bfd * abfd);
59*fae548d3Szrj static void write_archive (bfd *);
60*fae548d3Szrj static int ranlib_only (const char *archname);
61*fae548d3Szrj static int ranlib_touch (const char *archname);
62*fae548d3Szrj static void usage (int);
63*fae548d3Szrj
64*fae548d3Szrj /** Globals and flags. */
65*fae548d3Szrj
66*fae548d3Szrj static int mri_mode;
67*fae548d3Szrj
68*fae548d3Szrj /* This flag distinguishes between ar and ranlib:
69*fae548d3Szrj 1 means this is 'ranlib'; 0 means this is 'ar'.
70*fae548d3Szrj -1 means if we should use argv[0] to decide. */
71*fae548d3Szrj extern int is_ranlib;
72*fae548d3Szrj
73*fae548d3Szrj /* Nonzero means don't warn about creating the archive file if necessary. */
74*fae548d3Szrj int silent_create = 0;
75*fae548d3Szrj
76*fae548d3Szrj /* Nonzero means describe each action performed. */
77*fae548d3Szrj int verbose = 0;
78*fae548d3Szrj
79*fae548d3Szrj /* Nonzero means display offsets of files in the archive. */
80*fae548d3Szrj int display_offsets = 0;
81*fae548d3Szrj
82*fae548d3Szrj /* Nonzero means preserve dates of members when extracting them. */
83*fae548d3Szrj int preserve_dates = 0;
84*fae548d3Szrj
85*fae548d3Szrj /* Nonzero means don't replace existing members whose dates are more recent
86*fae548d3Szrj than the corresponding files. */
87*fae548d3Szrj int newer_only = 0;
88*fae548d3Szrj
89*fae548d3Szrj /* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
90*fae548d3Szrj member). -1 means we've been explicitly asked to not write a symbol table;
91*fae548d3Szrj +1 means we've been explicitly asked to write it;
92*fae548d3Szrj 0 is the default.
93*fae548d3Szrj Traditionally, the default in BSD has been to not write the table.
94*fae548d3Szrj However, for POSIX.2 compliance the default is now to write a symbol table
95*fae548d3Szrj if any of the members are object files. */
96*fae548d3Szrj int write_armap = 0;
97*fae548d3Szrj
98*fae548d3Szrj /* Operate in deterministic mode: write zero for timestamps, uids,
99*fae548d3Szrj and gids for archive members and the archive symbol table, and write
100*fae548d3Szrj consistent file modes. */
101*fae548d3Szrj int deterministic = -1; /* Determinism indeterminate. */
102*fae548d3Szrj
103*fae548d3Szrj /* Nonzero means it's the name of an existing member; position new or moved
104*fae548d3Szrj files with respect to this one. */
105*fae548d3Szrj char *posname = NULL;
106*fae548d3Szrj
107*fae548d3Szrj /* Sez how to use `posname': pos_before means position before that member.
108*fae548d3Szrj pos_after means position after that member. pos_end means always at end.
109*fae548d3Szrj pos_default means default appropriately. For the latter two, `posname'
110*fae548d3Szrj should also be zero. */
111*fae548d3Szrj enum pos
112*fae548d3Szrj {
113*fae548d3Szrj pos_default, pos_before, pos_after, pos_end
114*fae548d3Szrj } postype = pos_default;
115*fae548d3Szrj
116*fae548d3Szrj enum operations
117*fae548d3Szrj {
118*fae548d3Szrj none = 0, del, replace, print_table,
119*fae548d3Szrj print_files, extract, move, quick_append
120*fae548d3Szrj } operation = none;
121*fae548d3Szrj
122*fae548d3Szrj static bfd **
123*fae548d3Szrj get_pos_bfd (bfd **, enum pos, const char *);
124*fae548d3Szrj
125*fae548d3Szrj /* For extract/delete only. If COUNTED_NAME_MODE is TRUE, we only
126*fae548d3Szrj extract the COUNTED_NAME_COUNTER instance of that name. */
127*fae548d3Szrj static bfd_boolean counted_name_mode = 0;
128*fae548d3Szrj static int counted_name_counter = 0;
129*fae548d3Szrj
130*fae548d3Szrj /* Whether to truncate names of files stored in the archive. */
131*fae548d3Szrj static bfd_boolean ar_truncate = FALSE;
132*fae548d3Szrj
133*fae548d3Szrj /* Whether to use a full file name match when searching an archive.
134*fae548d3Szrj This is convenient for archives created by the Microsoft lib
135*fae548d3Szrj program. */
136*fae548d3Szrj static bfd_boolean full_pathname = FALSE;
137*fae548d3Szrj
138*fae548d3Szrj /* Whether to create a "thin" archive (symbol index only -- no files). */
139*fae548d3Szrj static bfd_boolean make_thin_archive = FALSE;
140*fae548d3Szrj
141*fae548d3Szrj static int show_version = 0;
142*fae548d3Szrj
143*fae548d3Szrj static int show_help = 0;
144*fae548d3Szrj
145*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
146*fae548d3Szrj static const char *plugin_target = "plugin";
147*fae548d3Szrj #else
148*fae548d3Szrj static const char *plugin_target = NULL;
149*fae548d3Szrj #endif
150*fae548d3Szrj
151*fae548d3Szrj static const char *target = NULL;
152*fae548d3Szrj
153*fae548d3Szrj enum long_option_numbers
154*fae548d3Szrj {
155*fae548d3Szrj OPTION_PLUGIN = 201,
156*fae548d3Szrj OPTION_TARGET,
157*fae548d3Szrj OPTION_OUTPUT
158*fae548d3Szrj };
159*fae548d3Szrj
160*fae548d3Szrj static const char * output_dir = NULL;
161*fae548d3Szrj
162*fae548d3Szrj static struct option long_options[] =
163*fae548d3Szrj {
164*fae548d3Szrj {"help", no_argument, &show_help, 1},
165*fae548d3Szrj {"plugin", required_argument, NULL, OPTION_PLUGIN},
166*fae548d3Szrj {"target", required_argument, NULL, OPTION_TARGET},
167*fae548d3Szrj {"version", no_argument, &show_version, 1},
168*fae548d3Szrj {"output", required_argument, NULL, OPTION_OUTPUT},
169*fae548d3Szrj {NULL, no_argument, NULL, 0}
170*fae548d3Szrj };
171*fae548d3Szrj
172*fae548d3Szrj int interactive = 0;
173*fae548d3Szrj
174*fae548d3Szrj static void
mri_emul(void)175*fae548d3Szrj mri_emul (void)
176*fae548d3Szrj {
177*fae548d3Szrj interactive = isatty (fileno (stdin));
178*fae548d3Szrj yyparse ();
179*fae548d3Szrj }
180*fae548d3Szrj
181*fae548d3Szrj /* If COUNT is 0, then FUNCTION is called once on each entry. If nonzero,
182*fae548d3Szrj COUNT is the length of the FILES chain; FUNCTION is called on each entry
183*fae548d3Szrj whose name matches one in FILES. */
184*fae548d3Szrj
185*fae548d3Szrj static void
map_over_members(bfd * arch,void (* function)(bfd *),char ** files,int count)186*fae548d3Szrj map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
187*fae548d3Szrj {
188*fae548d3Szrj bfd *head;
189*fae548d3Szrj int match_count;
190*fae548d3Szrj
191*fae548d3Szrj if (count == 0)
192*fae548d3Szrj {
193*fae548d3Szrj for (head = arch->archive_next; head; head = head->archive_next)
194*fae548d3Szrj {
195*fae548d3Szrj PROGRESS (1);
196*fae548d3Szrj function (head);
197*fae548d3Szrj }
198*fae548d3Szrj return;
199*fae548d3Szrj }
200*fae548d3Szrj
201*fae548d3Szrj /* This may appear to be a baroque way of accomplishing what we want.
202*fae548d3Szrj However we have to iterate over the filenames in order to notice where
203*fae548d3Szrj a filename is requested but does not exist in the archive. Ditto
204*fae548d3Szrj mapping over each file each time -- we want to hack multiple
205*fae548d3Szrj references. */
206*fae548d3Szrj
207*fae548d3Szrj for (head = arch->archive_next; head; head = head->archive_next)
208*fae548d3Szrj head->archive_pass = 0;
209*fae548d3Szrj
210*fae548d3Szrj for (; count > 0; files++, count--)
211*fae548d3Szrj {
212*fae548d3Szrj bfd_boolean found = FALSE;
213*fae548d3Szrj
214*fae548d3Szrj match_count = 0;
215*fae548d3Szrj for (head = arch->archive_next; head; head = head->archive_next)
216*fae548d3Szrj {
217*fae548d3Szrj const char * filename;
218*fae548d3Szrj
219*fae548d3Szrj PROGRESS (1);
220*fae548d3Szrj /* PR binutils/15796: Once an archive element has been matched
221*fae548d3Szrj do not match it again. If the user provides multiple same-named
222*fae548d3Szrj parameters on the command line their intent is to match multiple
223*fae548d3Szrj same-named entries in the archive, not the same entry multiple
224*fae548d3Szrj times. */
225*fae548d3Szrj if (head->archive_pass)
226*fae548d3Szrj continue;
227*fae548d3Szrj
228*fae548d3Szrj filename = head->filename;
229*fae548d3Szrj if (filename == NULL)
230*fae548d3Szrj {
231*fae548d3Szrj /* Some archive formats don't get the filenames filled in
232*fae548d3Szrj until the elements are opened. */
233*fae548d3Szrj struct stat buf;
234*fae548d3Szrj bfd_stat_arch_elt (head, &buf);
235*fae548d3Szrj }
236*fae548d3Szrj else if (bfd_is_thin_archive (arch))
237*fae548d3Szrj {
238*fae548d3Szrj /* Thin archives store full pathnames. Need to normalize. */
239*fae548d3Szrj filename = normalize (filename, arch);
240*fae548d3Szrj }
241*fae548d3Szrj
242*fae548d3Szrj if (filename != NULL
243*fae548d3Szrj && !FILENAME_CMP (normalize (*files, arch), filename))
244*fae548d3Szrj {
245*fae548d3Szrj ++match_count;
246*fae548d3Szrj if (counted_name_mode
247*fae548d3Szrj && match_count != counted_name_counter)
248*fae548d3Szrj {
249*fae548d3Szrj /* Counting, and didn't match on count; go on to the
250*fae548d3Szrj next one. */
251*fae548d3Szrj continue;
252*fae548d3Szrj }
253*fae548d3Szrj
254*fae548d3Szrj found = TRUE;
255*fae548d3Szrj function (head);
256*fae548d3Szrj head->archive_pass = 1;
257*fae548d3Szrj /* PR binutils/15796: Once a file has been matched, do not
258*fae548d3Szrj match any more same-named files in the archive. If the
259*fae548d3Szrj user does want to match multiple same-name files in an
260*fae548d3Szrj archive they should provide multiple same-name parameters
261*fae548d3Szrj to the ar command. */
262*fae548d3Szrj break;
263*fae548d3Szrj }
264*fae548d3Szrj }
265*fae548d3Szrj
266*fae548d3Szrj if (!found)
267*fae548d3Szrj /* xgettext:c-format */
268*fae548d3Szrj fprintf (stderr, _("no entry %s in archive\n"), *files);
269*fae548d3Szrj }
270*fae548d3Szrj }
271*fae548d3Szrj
272*fae548d3Szrj bfd_boolean operation_alters_arch = FALSE;
273*fae548d3Szrj
274*fae548d3Szrj static void
usage(int help)275*fae548d3Szrj usage (int help)
276*fae548d3Szrj {
277*fae548d3Szrj FILE *s;
278*fae548d3Szrj
279*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
280*fae548d3Szrj /* xgettext:c-format */
281*fae548d3Szrj const char *command_line
282*fae548d3Szrj = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
283*fae548d3Szrj " [--plugin <name>] [member-name] [count] archive-file file...\n");
284*fae548d3Szrj
285*fae548d3Szrj #else
286*fae548d3Szrj /* xgettext:c-format */
287*fae548d3Szrj const char *command_line
288*fae548d3Szrj = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV]"
289*fae548d3Szrj " [member-name] [count] archive-file file...\n");
290*fae548d3Szrj #endif
291*fae548d3Szrj s = help ? stdout : stderr;
292*fae548d3Szrj
293*fae548d3Szrj fprintf (s, command_line, program_name);
294*fae548d3Szrj
295*fae548d3Szrj /* xgettext:c-format */
296*fae548d3Szrj fprintf (s, _(" %s -M [<mri-script]\n"), program_name);
297*fae548d3Szrj fprintf (s, _(" commands:\n"));
298*fae548d3Szrj fprintf (s, _(" d - delete file(s) from the archive\n"));
299*fae548d3Szrj fprintf (s, _(" m[ab] - move file(s) in the archive\n"));
300*fae548d3Szrj fprintf (s, _(" p - print file(s) found in the archive\n"));
301*fae548d3Szrj fprintf (s, _(" q[f] - quick append file(s) to the archive\n"));
302*fae548d3Szrj fprintf (s, _(" r[ab][f][u] - replace existing or insert new file(s) into the archive\n"));
303*fae548d3Szrj fprintf (s, _(" s - act as ranlib\n"));
304*fae548d3Szrj fprintf (s, _(" t[O][v] - display contents of the archive\n"));
305*fae548d3Szrj fprintf (s, _(" x[o] - extract file(s) from the archive\n"));
306*fae548d3Szrj fprintf (s, _(" command specific modifiers:\n"));
307*fae548d3Szrj fprintf (s, _(" [a] - put file(s) after [member-name]\n"));
308*fae548d3Szrj fprintf (s, _(" [b] - put file(s) before [member-name] (same as [i])\n"));
309*fae548d3Szrj if (DEFAULT_AR_DETERMINISTIC)
310*fae548d3Szrj {
311*fae548d3Szrj fprintf (s, _("\
312*fae548d3Szrj [D] - use zero for timestamps and uids/gids (default)\n"));
313*fae548d3Szrj fprintf (s, _("\
314*fae548d3Szrj [U] - use actual timestamps and uids/gids\n"));
315*fae548d3Szrj }
316*fae548d3Szrj else
317*fae548d3Szrj {
318*fae548d3Szrj fprintf (s, _("\
319*fae548d3Szrj [D] - use zero for timestamps and uids/gids\n"));
320*fae548d3Szrj fprintf (s, _("\
321*fae548d3Szrj [U] - use actual timestamps and uids/gids (default)\n"));
322*fae548d3Szrj }
323*fae548d3Szrj fprintf (s, _(" [N] - use instance [count] of name\n"));
324*fae548d3Szrj fprintf (s, _(" [f] - truncate inserted file names\n"));
325*fae548d3Szrj fprintf (s, _(" [P] - use full path names when matching\n"));
326*fae548d3Szrj fprintf (s, _(" [o] - preserve original dates\n"));
327*fae548d3Szrj fprintf (s, _(" [O] - display offsets of files in the archive\n"));
328*fae548d3Szrj fprintf (s, _(" [u] - only replace files that are newer than current archive contents\n"));
329*fae548d3Szrj fprintf (s, _(" generic modifiers:\n"));
330*fae548d3Szrj fprintf (s, _(" [c] - do not warn if the library had to be created\n"));
331*fae548d3Szrj fprintf (s, _(" [s] - create an archive index (cf. ranlib)\n"));
332*fae548d3Szrj fprintf (s, _(" [S] - do not build a symbol table\n"));
333*fae548d3Szrj fprintf (s, _(" [T] - make a thin archive\n"));
334*fae548d3Szrj fprintf (s, _(" [v] - be verbose\n"));
335*fae548d3Szrj fprintf (s, _(" [V] - display the version number\n"));
336*fae548d3Szrj fprintf (s, _(" @<file> - read options from <file>\n"));
337*fae548d3Szrj fprintf (s, _(" --target=BFDNAME - specify the target object format as BFDNAME\n"));
338*fae548d3Szrj fprintf (s, _(" --output=DIRNAME - specify the output directory for extraction operations\n"));
339*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
340*fae548d3Szrj fprintf (s, _(" optional:\n"));
341*fae548d3Szrj fprintf (s, _(" --plugin <p> - load the specified plugin\n"));
342*fae548d3Szrj #endif
343*fae548d3Szrj
344*fae548d3Szrj ar_emul_usage (s);
345*fae548d3Szrj
346*fae548d3Szrj list_supported_targets (program_name, s);
347*fae548d3Szrj
348*fae548d3Szrj if (REPORT_BUGS_TO[0] && help)
349*fae548d3Szrj fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
350*fae548d3Szrj
351*fae548d3Szrj xexit (help ? 0 : 1);
352*fae548d3Szrj }
353*fae548d3Szrj
354*fae548d3Szrj static void
ranlib_usage(int help)355*fae548d3Szrj ranlib_usage (int help)
356*fae548d3Szrj {
357*fae548d3Szrj FILE *s;
358*fae548d3Szrj
359*fae548d3Szrj s = help ? stdout : stderr;
360*fae548d3Szrj
361*fae548d3Szrj /* xgettext:c-format */
362*fae548d3Szrj fprintf (s, _("Usage: %s [options] archive\n"), program_name);
363*fae548d3Szrj fprintf (s, _(" Generate an index to speed access to archives\n"));
364*fae548d3Szrj fprintf (s, _(" The options are:\n\
365*fae548d3Szrj @<file> Read options from <file>\n"));
366*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
367*fae548d3Szrj fprintf (s, _("\
368*fae548d3Szrj --plugin <name> Load the specified plugin\n"));
369*fae548d3Szrj #endif
370*fae548d3Szrj if (DEFAULT_AR_DETERMINISTIC)
371*fae548d3Szrj fprintf (s, _("\
372*fae548d3Szrj -D Use zero for symbol map timestamp (default)\n\
373*fae548d3Szrj -U Use an actual symbol map timestamp\n"));
374*fae548d3Szrj else
375*fae548d3Szrj fprintf (s, _("\
376*fae548d3Szrj -D Use zero for symbol map timestamp\n\
377*fae548d3Szrj -U Use actual symbol map timestamp (default)\n"));
378*fae548d3Szrj fprintf (s, _("\
379*fae548d3Szrj -t Update the archive's symbol map timestamp\n\
380*fae548d3Szrj -h --help Print this help message\n\
381*fae548d3Szrj -v --version Print version information\n"));
382*fae548d3Szrj
383*fae548d3Szrj list_supported_targets (program_name, s);
384*fae548d3Szrj
385*fae548d3Szrj if (REPORT_BUGS_TO[0] && help)
386*fae548d3Szrj fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
387*fae548d3Szrj
388*fae548d3Szrj xexit (help ? 0 : 1);
389*fae548d3Szrj }
390*fae548d3Szrj
391*fae548d3Szrj /* Normalize a file name specified on the command line into a file
392*fae548d3Szrj name which we will use in an archive. */
393*fae548d3Szrj
394*fae548d3Szrj static const char *
normalize(const char * file,bfd * abfd)395*fae548d3Szrj normalize (const char *file, bfd *abfd)
396*fae548d3Szrj {
397*fae548d3Szrj const char *filename;
398*fae548d3Szrj
399*fae548d3Szrj if (full_pathname)
400*fae548d3Szrj return file;
401*fae548d3Szrj
402*fae548d3Szrj filename = lbasename (file);
403*fae548d3Szrj
404*fae548d3Szrj if (ar_truncate
405*fae548d3Szrj && abfd != NULL
406*fae548d3Szrj && strlen (filename) > abfd->xvec->ar_max_namelen)
407*fae548d3Szrj {
408*fae548d3Szrj char *s;
409*fae548d3Szrj
410*fae548d3Szrj /* Space leak. */
411*fae548d3Szrj s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
412*fae548d3Szrj memcpy (s, filename, abfd->xvec->ar_max_namelen);
413*fae548d3Szrj s[abfd->xvec->ar_max_namelen] = '\0';
414*fae548d3Szrj filename = s;
415*fae548d3Szrj }
416*fae548d3Szrj
417*fae548d3Szrj return filename;
418*fae548d3Szrj }
419*fae548d3Szrj
420*fae548d3Szrj /* Remove any output file. This is only called via xatexit. */
421*fae548d3Szrj
422*fae548d3Szrj static const char *output_filename = NULL;
423*fae548d3Szrj static FILE *output_file = NULL;
424*fae548d3Szrj static bfd *output_bfd = NULL;
425*fae548d3Szrj
426*fae548d3Szrj static void
remove_output(void)427*fae548d3Szrj remove_output (void)
428*fae548d3Szrj {
429*fae548d3Szrj if (output_filename != NULL)
430*fae548d3Szrj {
431*fae548d3Szrj if (output_bfd != NULL)
432*fae548d3Szrj bfd_cache_close (output_bfd);
433*fae548d3Szrj if (output_file != NULL)
434*fae548d3Szrj fclose (output_file);
435*fae548d3Szrj unlink_if_ordinary (output_filename);
436*fae548d3Szrj }
437*fae548d3Szrj }
438*fae548d3Szrj
439*fae548d3Szrj static char **
decode_options(int argc,char ** argv)440*fae548d3Szrj decode_options (int argc, char **argv)
441*fae548d3Szrj {
442*fae548d3Szrj int c;
443*fae548d3Szrj
444*fae548d3Szrj /* Convert old-style ar call by exploding option element and rearranging
445*fae548d3Szrj options accordingly. */
446*fae548d3Szrj
447*fae548d3Szrj restart:
448*fae548d3Szrj if (argc > 1 && argv[1][0] != '-')
449*fae548d3Szrj {
450*fae548d3Szrj int new_argc; /* argc value for rearranged arguments */
451*fae548d3Szrj char **new_argv; /* argv value for rearranged arguments */
452*fae548d3Szrj char *const *in; /* cursor into original argv */
453*fae548d3Szrj char **out; /* cursor into rearranged argv */
454*fae548d3Szrj const char *letter; /* cursor into old option letters */
455*fae548d3Szrj char buffer[3]; /* constructed option buffer */
456*fae548d3Szrj
457*fae548d3Szrj /* Initialize a constructed option. */
458*fae548d3Szrj
459*fae548d3Szrj buffer[0] = '-';
460*fae548d3Szrj buffer[2] = '\0';
461*fae548d3Szrj
462*fae548d3Szrj /* Allocate a new argument array, and copy program name in it. */
463*fae548d3Szrj
464*fae548d3Szrj new_argc = argc - 1 + strlen (argv[1]);
465*fae548d3Szrj new_argv = xmalloc ((new_argc + 1) * sizeof (*argv));
466*fae548d3Szrj in = argv;
467*fae548d3Szrj out = new_argv;
468*fae548d3Szrj *out++ = *in++;
469*fae548d3Szrj
470*fae548d3Szrj /* Copy each old letter option as a separate option. */
471*fae548d3Szrj
472*fae548d3Szrj for (letter = *in++; *letter; letter++)
473*fae548d3Szrj {
474*fae548d3Szrj buffer[1] = *letter;
475*fae548d3Szrj *out++ = xstrdup (buffer);
476*fae548d3Szrj }
477*fae548d3Szrj
478*fae548d3Szrj /* Copy all remaining options. */
479*fae548d3Szrj
480*fae548d3Szrj while (in < argv + argc)
481*fae548d3Szrj *out++ = *in++;
482*fae548d3Szrj *out = NULL;
483*fae548d3Szrj
484*fae548d3Szrj /* Replace the old option list by the new one. */
485*fae548d3Szrj
486*fae548d3Szrj argc = new_argc;
487*fae548d3Szrj argv = new_argv;
488*fae548d3Szrj }
489*fae548d3Szrj
490*fae548d3Szrj while ((c = getopt_long (argc, argv, "hdmpqrtxlcoOVsSuvabiMNfPTDU",
491*fae548d3Szrj long_options, NULL)) != EOF)
492*fae548d3Szrj {
493*fae548d3Szrj switch (c)
494*fae548d3Szrj {
495*fae548d3Szrj case 'd':
496*fae548d3Szrj case 'm':
497*fae548d3Szrj case 'p':
498*fae548d3Szrj case 'q':
499*fae548d3Szrj case 'r':
500*fae548d3Szrj case 't':
501*fae548d3Szrj case 'x':
502*fae548d3Szrj if (operation != none)
503*fae548d3Szrj fatal (_("two different operation options specified"));
504*fae548d3Szrj break;
505*fae548d3Szrj }
506*fae548d3Szrj
507*fae548d3Szrj switch (c)
508*fae548d3Szrj {
509*fae548d3Szrj case 'h':
510*fae548d3Szrj show_help = 1;
511*fae548d3Szrj break;
512*fae548d3Szrj case 'd':
513*fae548d3Szrj operation = del;
514*fae548d3Szrj operation_alters_arch = TRUE;
515*fae548d3Szrj break;
516*fae548d3Szrj case 'm':
517*fae548d3Szrj operation = move;
518*fae548d3Szrj operation_alters_arch = TRUE;
519*fae548d3Szrj break;
520*fae548d3Szrj case 'p':
521*fae548d3Szrj operation = print_files;
522*fae548d3Szrj break;
523*fae548d3Szrj case 'q':
524*fae548d3Szrj operation = quick_append;
525*fae548d3Szrj operation_alters_arch = TRUE;
526*fae548d3Szrj break;
527*fae548d3Szrj case 'r':
528*fae548d3Szrj operation = replace;
529*fae548d3Szrj operation_alters_arch = TRUE;
530*fae548d3Szrj break;
531*fae548d3Szrj case 't':
532*fae548d3Szrj operation = print_table;
533*fae548d3Szrj break;
534*fae548d3Szrj case 'x':
535*fae548d3Szrj operation = extract;
536*fae548d3Szrj break;
537*fae548d3Szrj case 'l':
538*fae548d3Szrj break;
539*fae548d3Szrj case 'c':
540*fae548d3Szrj silent_create = 1;
541*fae548d3Szrj break;
542*fae548d3Szrj case 'o':
543*fae548d3Szrj preserve_dates = 1;
544*fae548d3Szrj break;
545*fae548d3Szrj case 'O':
546*fae548d3Szrj display_offsets = 1;
547*fae548d3Szrj break;
548*fae548d3Szrj case 'V':
549*fae548d3Szrj show_version = TRUE;
550*fae548d3Szrj break;
551*fae548d3Szrj case 's':
552*fae548d3Szrj write_armap = 1;
553*fae548d3Szrj break;
554*fae548d3Szrj case 'S':
555*fae548d3Szrj write_armap = -1;
556*fae548d3Szrj break;
557*fae548d3Szrj case 'u':
558*fae548d3Szrj newer_only = 1;
559*fae548d3Szrj break;
560*fae548d3Szrj case 'v':
561*fae548d3Szrj verbose = 1;
562*fae548d3Szrj break;
563*fae548d3Szrj case 'a':
564*fae548d3Szrj postype = pos_after;
565*fae548d3Szrj break;
566*fae548d3Szrj case 'b':
567*fae548d3Szrj postype = pos_before;
568*fae548d3Szrj break;
569*fae548d3Szrj case 'i':
570*fae548d3Szrj postype = pos_before;
571*fae548d3Szrj break;
572*fae548d3Szrj case 'M':
573*fae548d3Szrj mri_mode = 1;
574*fae548d3Szrj break;
575*fae548d3Szrj case 'N':
576*fae548d3Szrj counted_name_mode = TRUE;
577*fae548d3Szrj break;
578*fae548d3Szrj case 'f':
579*fae548d3Szrj ar_truncate = TRUE;
580*fae548d3Szrj break;
581*fae548d3Szrj case 'P':
582*fae548d3Szrj full_pathname = TRUE;
583*fae548d3Szrj break;
584*fae548d3Szrj case 'T':
585*fae548d3Szrj make_thin_archive = TRUE;
586*fae548d3Szrj break;
587*fae548d3Szrj case 'D':
588*fae548d3Szrj deterministic = TRUE;
589*fae548d3Szrj break;
590*fae548d3Szrj case 'U':
591*fae548d3Szrj deterministic = FALSE;
592*fae548d3Szrj break;
593*fae548d3Szrj case OPTION_PLUGIN:
594*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
595*fae548d3Szrj bfd_plugin_set_plugin (optarg);
596*fae548d3Szrj #else
597*fae548d3Szrj fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
598*fae548d3Szrj xexit (1);
599*fae548d3Szrj #endif
600*fae548d3Szrj break;
601*fae548d3Szrj case OPTION_TARGET:
602*fae548d3Szrj target = optarg;
603*fae548d3Szrj break;
604*fae548d3Szrj case OPTION_OUTPUT:
605*fae548d3Szrj output_dir = optarg;
606*fae548d3Szrj break;
607*fae548d3Szrj case 0: /* A long option that just sets a flag. */
608*fae548d3Szrj break;
609*fae548d3Szrj default:
610*fae548d3Szrj usage (0);
611*fae548d3Szrj }
612*fae548d3Szrj }
613*fae548d3Szrj
614*fae548d3Szrj /* PR 13256: Allow for the possibility that the first command line option
615*fae548d3Szrj started with a dash (eg --plugin) but then the following option(s) are
616*fae548d3Szrj old style, non-dash-prefixed versions. */
617*fae548d3Szrj if (operation == none && write_armap != 1 && !mri_mode
618*fae548d3Szrj && optind > 0 && optind < argc)
619*fae548d3Szrj {
620*fae548d3Szrj argv += (optind - 1);
621*fae548d3Szrj argc -= (optind - 1);
622*fae548d3Szrj optind = 0;
623*fae548d3Szrj goto restart;
624*fae548d3Szrj }
625*fae548d3Szrj
626*fae548d3Szrj return &argv[optind];
627*fae548d3Szrj }
628*fae548d3Szrj
629*fae548d3Szrj /* If neither -D nor -U was specified explicitly,
630*fae548d3Szrj then use the configured default. */
631*fae548d3Szrj static void
default_deterministic(void)632*fae548d3Szrj default_deterministic (void)
633*fae548d3Szrj {
634*fae548d3Szrj if (deterministic < 0)
635*fae548d3Szrj deterministic = DEFAULT_AR_DETERMINISTIC;
636*fae548d3Szrj }
637*fae548d3Szrj
638*fae548d3Szrj static void
ranlib_main(int argc,char ** argv)639*fae548d3Szrj ranlib_main (int argc, char **argv)
640*fae548d3Szrj {
641*fae548d3Szrj int arg_index, status = 0;
642*fae548d3Szrj bfd_boolean touch = FALSE;
643*fae548d3Szrj int c;
644*fae548d3Szrj
645*fae548d3Szrj while ((c = getopt_long (argc, argv, "DhHUvVt", long_options, NULL)) != EOF)
646*fae548d3Szrj {
647*fae548d3Szrj switch (c)
648*fae548d3Szrj {
649*fae548d3Szrj case 'D':
650*fae548d3Szrj deterministic = TRUE;
651*fae548d3Szrj break;
652*fae548d3Szrj case 'U':
653*fae548d3Szrj deterministic = FALSE;
654*fae548d3Szrj break;
655*fae548d3Szrj case 'h':
656*fae548d3Szrj case 'H':
657*fae548d3Szrj show_help = 1;
658*fae548d3Szrj break;
659*fae548d3Szrj case 't':
660*fae548d3Szrj touch = TRUE;
661*fae548d3Szrj break;
662*fae548d3Szrj case 'v':
663*fae548d3Szrj case 'V':
664*fae548d3Szrj show_version = 1;
665*fae548d3Szrj break;
666*fae548d3Szrj
667*fae548d3Szrj /* PR binutils/13493: Support plugins. */
668*fae548d3Szrj case OPTION_PLUGIN:
669*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
670*fae548d3Szrj bfd_plugin_set_plugin (optarg);
671*fae548d3Szrj #else
672*fae548d3Szrj fprintf (stderr, _("sorry - this program has been built without plugin support\n"));
673*fae548d3Szrj xexit (1);
674*fae548d3Szrj #endif
675*fae548d3Szrj break;
676*fae548d3Szrj }
677*fae548d3Szrj }
678*fae548d3Szrj
679*fae548d3Szrj if (argc < 2)
680*fae548d3Szrj ranlib_usage (0);
681*fae548d3Szrj
682*fae548d3Szrj if (show_help)
683*fae548d3Szrj ranlib_usage (1);
684*fae548d3Szrj
685*fae548d3Szrj if (show_version)
686*fae548d3Szrj print_version ("ranlib");
687*fae548d3Szrj
688*fae548d3Szrj default_deterministic ();
689*fae548d3Szrj
690*fae548d3Szrj arg_index = optind;
691*fae548d3Szrj
692*fae548d3Szrj while (arg_index < argc)
693*fae548d3Szrj {
694*fae548d3Szrj if (! touch)
695*fae548d3Szrj status |= ranlib_only (argv[arg_index]);
696*fae548d3Szrj else
697*fae548d3Szrj status |= ranlib_touch (argv[arg_index]);
698*fae548d3Szrj ++arg_index;
699*fae548d3Szrj }
700*fae548d3Szrj
701*fae548d3Szrj xexit (status);
702*fae548d3Szrj }
703*fae548d3Szrj
704*fae548d3Szrj int main (int, char **);
705*fae548d3Szrj
706*fae548d3Szrj int
main(int argc,char ** argv)707*fae548d3Szrj main (int argc, char **argv)
708*fae548d3Szrj {
709*fae548d3Szrj int arg_index;
710*fae548d3Szrj char **files;
711*fae548d3Szrj int file_count;
712*fae548d3Szrj char *inarch_filename;
713*fae548d3Szrj int i;
714*fae548d3Szrj
715*fae548d3Szrj #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
716*fae548d3Szrj setlocale (LC_MESSAGES, "");
717*fae548d3Szrj #endif
718*fae548d3Szrj #if defined (HAVE_SETLOCALE)
719*fae548d3Szrj setlocale (LC_CTYPE, "");
720*fae548d3Szrj #endif
721*fae548d3Szrj bindtextdomain (PACKAGE, LOCALEDIR);
722*fae548d3Szrj textdomain (PACKAGE);
723*fae548d3Szrj
724*fae548d3Szrj program_name = argv[0];
725*fae548d3Szrj xmalloc_set_program_name (program_name);
726*fae548d3Szrj bfd_set_error_program_name (program_name);
727*fae548d3Szrj #if BFD_SUPPORTS_PLUGINS
728*fae548d3Szrj bfd_plugin_set_program_name (program_name);
729*fae548d3Szrj #endif
730*fae548d3Szrj
731*fae548d3Szrj expandargv (&argc, &argv);
732*fae548d3Szrj
733*fae548d3Szrj if (is_ranlib < 0)
734*fae548d3Szrj {
735*fae548d3Szrj const char *temp = lbasename (program_name);
736*fae548d3Szrj
737*fae548d3Szrj if (strlen (temp) >= 6
738*fae548d3Szrj && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
739*fae548d3Szrj is_ranlib = 1;
740*fae548d3Szrj else
741*fae548d3Szrj is_ranlib = 0;
742*fae548d3Szrj }
743*fae548d3Szrj
744*fae548d3Szrj START_PROGRESS (program_name, 0);
745*fae548d3Szrj
746*fae548d3Szrj if (bfd_init () != BFD_INIT_MAGIC)
747*fae548d3Szrj fatal (_("fatal error: libbfd ABI mismatch"));
748*fae548d3Szrj set_default_bfd_target ();
749*fae548d3Szrj
750*fae548d3Szrj xatexit (remove_output);
751*fae548d3Szrj
752*fae548d3Szrj for (i = 1; i < argc; i++)
753*fae548d3Szrj if (! ar_emul_parse_arg (argv[i]))
754*fae548d3Szrj break;
755*fae548d3Szrj argv += (i - 1);
756*fae548d3Szrj argc -= (i - 1);
757*fae548d3Szrj
758*fae548d3Szrj if (is_ranlib)
759*fae548d3Szrj ranlib_main (argc, argv);
760*fae548d3Szrj
761*fae548d3Szrj if (argc < 2)
762*fae548d3Szrj usage (0);
763*fae548d3Szrj
764*fae548d3Szrj argv = decode_options (argc, argv);
765*fae548d3Szrj
766*fae548d3Szrj if (show_help)
767*fae548d3Szrj usage (1);
768*fae548d3Szrj
769*fae548d3Szrj if (show_version)
770*fae548d3Szrj print_version ("ar");
771*fae548d3Szrj
772*fae548d3Szrj arg_index = 0;
773*fae548d3Szrj
774*fae548d3Szrj if (mri_mode)
775*fae548d3Szrj {
776*fae548d3Szrj default_deterministic ();
777*fae548d3Szrj mri_emul ();
778*fae548d3Szrj }
779*fae548d3Szrj else
780*fae548d3Szrj {
781*fae548d3Szrj bfd *arch;
782*fae548d3Szrj
783*fae548d3Szrj /* Fail if no files are specified on the command line.
784*fae548d3Szrj (But not for MRI mode which allows for reading arguments
785*fae548d3Szrj and filenames from stdin). */
786*fae548d3Szrj if (argv[arg_index] == NULL)
787*fae548d3Szrj usage (0);
788*fae548d3Szrj
789*fae548d3Szrj /* We don't use do_quick_append any more. Too many systems
790*fae548d3Szrj expect ar to always rebuild the symbol table even when q is
791*fae548d3Szrj used. */
792*fae548d3Szrj
793*fae548d3Szrj /* We can't write an armap when using ar q, so just do ar r
794*fae548d3Szrj instead. */
795*fae548d3Szrj if (operation == quick_append && write_armap)
796*fae548d3Szrj operation = replace;
797*fae548d3Szrj
798*fae548d3Szrj if ((operation == none || operation == print_table)
799*fae548d3Szrj && write_armap == 1)
800*fae548d3Szrj xexit (ranlib_only (argv[arg_index]));
801*fae548d3Szrj
802*fae548d3Szrj if (operation == none)
803*fae548d3Szrj fatal (_("no operation specified"));
804*fae548d3Szrj
805*fae548d3Szrj if (newer_only && operation != replace)
806*fae548d3Szrj fatal (_("`u' is only meaningful with the `r' option."));
807*fae548d3Szrj
808*fae548d3Szrj if (newer_only && deterministic > 0)
809*fae548d3Szrj fatal (_("`u' is not meaningful with the `D' option."));
810*fae548d3Szrj
811*fae548d3Szrj if (newer_only && deterministic < 0 && DEFAULT_AR_DETERMINISTIC)
812*fae548d3Szrj non_fatal (_("\
813*fae548d3Szrj `u' modifier ignored since `D' is the default (see `U')"));
814*fae548d3Szrj
815*fae548d3Szrj default_deterministic ();
816*fae548d3Szrj
817*fae548d3Szrj if (postype != pos_default)
818*fae548d3Szrj {
819*fae548d3Szrj posname = argv[arg_index++];
820*fae548d3Szrj if (posname == NULL)
821*fae548d3Szrj fatal (_("missing position arg."));
822*fae548d3Szrj }
823*fae548d3Szrj
824*fae548d3Szrj if (counted_name_mode)
825*fae548d3Szrj {
826*fae548d3Szrj if (operation != extract && operation != del)
827*fae548d3Szrj fatal (_("`N' is only meaningful with the `x' and `d' options."));
828*fae548d3Szrj if (argv[arg_index] == NULL)
829*fae548d3Szrj fatal (_("`N' missing value."));
830*fae548d3Szrj counted_name_counter = atoi (argv[arg_index++]);
831*fae548d3Szrj if (counted_name_counter <= 0)
832*fae548d3Szrj fatal (_("Value for `N' must be positive."));
833*fae548d3Szrj }
834*fae548d3Szrj
835*fae548d3Szrj inarch_filename = argv[arg_index++];
836*fae548d3Szrj if (inarch_filename == NULL)
837*fae548d3Szrj usage (0);
838*fae548d3Szrj
839*fae548d3Szrj for (file_count = 0; argv[arg_index + file_count] != NULL; file_count++)
840*fae548d3Szrj continue;
841*fae548d3Szrj
842*fae548d3Szrj files = (file_count > 0) ? argv + arg_index : NULL;
843*fae548d3Szrj
844*fae548d3Szrj arch = open_inarch (inarch_filename,
845*fae548d3Szrj files == NULL ? (char *) NULL : files[0]);
846*fae548d3Szrj
847*fae548d3Szrj if (operation == extract && bfd_is_thin_archive (arch))
848*fae548d3Szrj fatal (_("`x' cannot be used on thin archives."));
849*fae548d3Szrj
850*fae548d3Szrj switch (operation)
851*fae548d3Szrj {
852*fae548d3Szrj case print_table:
853*fae548d3Szrj map_over_members (arch, print_descr, files, file_count);
854*fae548d3Szrj break;
855*fae548d3Szrj
856*fae548d3Szrj case print_files:
857*fae548d3Szrj map_over_members (arch, print_contents, files, file_count);
858*fae548d3Szrj break;
859*fae548d3Szrj
860*fae548d3Szrj case extract:
861*fae548d3Szrj map_over_members (arch, extract_file, files, file_count);
862*fae548d3Szrj break;
863*fae548d3Szrj
864*fae548d3Szrj case del:
865*fae548d3Szrj if (files != NULL)
866*fae548d3Szrj delete_members (arch, files);
867*fae548d3Szrj else
868*fae548d3Szrj output_filename = NULL;
869*fae548d3Szrj break;
870*fae548d3Szrj
871*fae548d3Szrj case move:
872*fae548d3Szrj /* PR 12558: Creating and moving at the same time does
873*fae548d3Szrj not make sense. Just create the archive instead. */
874*fae548d3Szrj if (! silent_create)
875*fae548d3Szrj {
876*fae548d3Szrj if (files != NULL)
877*fae548d3Szrj move_members (arch, files);
878*fae548d3Szrj else
879*fae548d3Szrj output_filename = NULL;
880*fae548d3Szrj break;
881*fae548d3Szrj }
882*fae548d3Szrj /* Fall through. */
883*fae548d3Szrj
884*fae548d3Szrj case replace:
885*fae548d3Szrj case quick_append:
886*fae548d3Szrj if (files != NULL || write_armap > 0)
887*fae548d3Szrj replace_members (arch, files, operation == quick_append);
888*fae548d3Szrj else
889*fae548d3Szrj output_filename = NULL;
890*fae548d3Szrj break;
891*fae548d3Szrj
892*fae548d3Szrj /* Shouldn't happen! */
893*fae548d3Szrj default:
894*fae548d3Szrj /* xgettext:c-format */
895*fae548d3Szrj fatal (_("internal error -- this option not implemented"));
896*fae548d3Szrj }
897*fae548d3Szrj }
898*fae548d3Szrj
899*fae548d3Szrj END_PROGRESS (program_name);
900*fae548d3Szrj
901*fae548d3Szrj xexit (0);
902*fae548d3Szrj return 0;
903*fae548d3Szrj }
904*fae548d3Szrj
905*fae548d3Szrj bfd *
open_inarch(const char * archive_filename,const char * file)906*fae548d3Szrj open_inarch (const char *archive_filename, const char *file)
907*fae548d3Szrj {
908*fae548d3Szrj bfd **last_one;
909*fae548d3Szrj bfd *next_one;
910*fae548d3Szrj struct stat sbuf;
911*fae548d3Szrj bfd *arch;
912*fae548d3Szrj char **matching;
913*fae548d3Szrj
914*fae548d3Szrj bfd_set_error (bfd_error_no_error);
915*fae548d3Szrj
916*fae548d3Szrj if (target == NULL)
917*fae548d3Szrj target = plugin_target;
918*fae548d3Szrj
919*fae548d3Szrj if (stat (archive_filename, &sbuf) != 0)
920*fae548d3Szrj {
921*fae548d3Szrj #if !defined(__GO32__) || defined(__DJGPP__)
922*fae548d3Szrj
923*fae548d3Szrj /* FIXME: I don't understand why this fragment was ifndef'ed
924*fae548d3Szrj away for __GO32__; perhaps it was in the days of DJGPP v1.x.
925*fae548d3Szrj stat() works just fine in v2.x, so I think this should be
926*fae548d3Szrj removed. For now, I enable it for DJGPP v2. -- EZ. */
927*fae548d3Szrj
928*fae548d3Szrj /* KLUDGE ALERT! Temporary fix until I figger why
929*fae548d3Szrj stat() is wrong ... think it's buried in GO32's IDT - Jax */
930*fae548d3Szrj if (errno != ENOENT)
931*fae548d3Szrj bfd_fatal (archive_filename);
932*fae548d3Szrj #endif
933*fae548d3Szrj
934*fae548d3Szrj if (!operation_alters_arch)
935*fae548d3Szrj {
936*fae548d3Szrj fprintf (stderr, "%s: ", program_name);
937*fae548d3Szrj perror (archive_filename);
938*fae548d3Szrj maybequit ();
939*fae548d3Szrj return NULL;
940*fae548d3Szrj }
941*fae548d3Szrj
942*fae548d3Szrj /* If the target isn't set, try to figure out the target to use
943*fae548d3Szrj for the archive from the first object on the list. */
944*fae548d3Szrj if (target == NULL && file != NULL)
945*fae548d3Szrj {
946*fae548d3Szrj bfd *obj;
947*fae548d3Szrj
948*fae548d3Szrj obj = bfd_openr (file, target);
949*fae548d3Szrj if (obj != NULL)
950*fae548d3Szrj {
951*fae548d3Szrj if (bfd_check_format (obj, bfd_object))
952*fae548d3Szrj target = bfd_get_target (obj);
953*fae548d3Szrj (void) bfd_close (obj);
954*fae548d3Szrj }
955*fae548d3Szrj }
956*fae548d3Szrj
957*fae548d3Szrj /* Create an empty archive. */
958*fae548d3Szrj arch = bfd_openw (archive_filename, target);
959*fae548d3Szrj if (arch == NULL
960*fae548d3Szrj || ! bfd_set_format (arch, bfd_archive)
961*fae548d3Szrj || ! bfd_close (arch))
962*fae548d3Szrj bfd_fatal (archive_filename);
963*fae548d3Szrj else if (!silent_create)
964*fae548d3Szrj non_fatal (_("creating %s"), archive_filename);
965*fae548d3Szrj
966*fae548d3Szrj /* If we die creating a new archive, don't leave it around. */
967*fae548d3Szrj output_filename = archive_filename;
968*fae548d3Szrj }
969*fae548d3Szrj
970*fae548d3Szrj arch = bfd_openr (archive_filename, target);
971*fae548d3Szrj if (arch == NULL)
972*fae548d3Szrj {
973*fae548d3Szrj bloser:
974*fae548d3Szrj bfd_fatal (archive_filename);
975*fae548d3Szrj }
976*fae548d3Szrj
977*fae548d3Szrj if (! bfd_check_format_matches (arch, bfd_archive, &matching))
978*fae548d3Szrj {
979*fae548d3Szrj bfd_nonfatal (archive_filename);
980*fae548d3Szrj if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
981*fae548d3Szrj {
982*fae548d3Szrj list_matching_formats (matching);
983*fae548d3Szrj free (matching);
984*fae548d3Szrj }
985*fae548d3Szrj xexit (1);
986*fae548d3Szrj }
987*fae548d3Szrj
988*fae548d3Szrj if ((operation == replace || operation == quick_append)
989*fae548d3Szrj && bfd_openr_next_archived_file (arch, NULL) != NULL)
990*fae548d3Szrj {
991*fae548d3Szrj /* PR 15140: Catch attempts to convert a normal
992*fae548d3Szrj archive into a thin archive or vice versa. */
993*fae548d3Szrj if (make_thin_archive && ! bfd_is_thin_archive (arch))
994*fae548d3Szrj {
995*fae548d3Szrj fatal (_("Cannot convert existing library %s to thin format"),
996*fae548d3Szrj bfd_get_filename (arch));
997*fae548d3Szrj goto bloser;
998*fae548d3Szrj }
999*fae548d3Szrj else if (! make_thin_archive && bfd_is_thin_archive (arch))
1000*fae548d3Szrj {
1001*fae548d3Szrj fatal (_("Cannot convert existing thin library %s to normal format"),
1002*fae548d3Szrj bfd_get_filename (arch));
1003*fae548d3Szrj goto bloser;
1004*fae548d3Szrj }
1005*fae548d3Szrj }
1006*fae548d3Szrj
1007*fae548d3Szrj last_one = &(arch->archive_next);
1008*fae548d3Szrj /* Read all the contents right away, regardless. */
1009*fae548d3Szrj for (next_one = bfd_openr_next_archived_file (arch, NULL);
1010*fae548d3Szrj next_one;
1011*fae548d3Szrj next_one = bfd_openr_next_archived_file (arch, next_one))
1012*fae548d3Szrj {
1013*fae548d3Szrj PROGRESS (1);
1014*fae548d3Szrj *last_one = next_one;
1015*fae548d3Szrj last_one = &next_one->archive_next;
1016*fae548d3Szrj }
1017*fae548d3Szrj *last_one = (bfd *) NULL;
1018*fae548d3Szrj if (bfd_get_error () != bfd_error_no_more_archived_files)
1019*fae548d3Szrj goto bloser;
1020*fae548d3Szrj return arch;
1021*fae548d3Szrj }
1022*fae548d3Szrj
1023*fae548d3Szrj static void
print_contents(bfd * abfd)1024*fae548d3Szrj print_contents (bfd *abfd)
1025*fae548d3Szrj {
1026*fae548d3Szrj bfd_size_type ncopied = 0;
1027*fae548d3Szrj bfd_size_type size;
1028*fae548d3Szrj char *cbuf = (char *) xmalloc (BUFSIZE);
1029*fae548d3Szrj struct stat buf;
1030*fae548d3Szrj
1031*fae548d3Szrj if (bfd_stat_arch_elt (abfd, &buf) != 0)
1032*fae548d3Szrj /* xgettext:c-format */
1033*fae548d3Szrj fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
1034*fae548d3Szrj
1035*fae548d3Szrj if (verbose)
1036*fae548d3Szrj printf ("\n<%s>\n\n", bfd_get_filename (abfd));
1037*fae548d3Szrj
1038*fae548d3Szrj bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
1039*fae548d3Szrj
1040*fae548d3Szrj size = buf.st_size;
1041*fae548d3Szrj while (ncopied < size)
1042*fae548d3Szrj {
1043*fae548d3Szrj bfd_size_type nread;
1044*fae548d3Szrj bfd_size_type tocopy = size - ncopied;
1045*fae548d3Szrj
1046*fae548d3Szrj if (tocopy > BUFSIZE)
1047*fae548d3Szrj tocopy = BUFSIZE;
1048*fae548d3Szrj
1049*fae548d3Szrj nread = bfd_bread (cbuf, tocopy, abfd);
1050*fae548d3Szrj if (nread != tocopy)
1051*fae548d3Szrj /* xgettext:c-format */
1052*fae548d3Szrj fatal (_("%s is not a valid archive"),
1053*fae548d3Szrj bfd_get_filename (abfd->my_archive));
1054*fae548d3Szrj
1055*fae548d3Szrj /* fwrite in mingw32 may return int instead of bfd_size_type. Cast the
1056*fae548d3Szrj return value to bfd_size_type to avoid comparison between signed and
1057*fae548d3Szrj unsigned values. */
1058*fae548d3Szrj if ((bfd_size_type) fwrite (cbuf, 1, nread, stdout) != nread)
1059*fae548d3Szrj fatal ("stdout: %s", strerror (errno));
1060*fae548d3Szrj ncopied += tocopy;
1061*fae548d3Szrj }
1062*fae548d3Szrj free (cbuf);
1063*fae548d3Szrj }
1064*fae548d3Szrj
1065*fae548d3Szrj
1066*fae548d3Szrj static FILE * open_output_file (bfd *) ATTRIBUTE_RETURNS_NONNULL;
1067*fae548d3Szrj
1068*fae548d3Szrj static FILE *
open_output_file(bfd * abfd)1069*fae548d3Szrj open_output_file (bfd * abfd)
1070*fae548d3Szrj {
1071*fae548d3Szrj output_filename = bfd_get_filename (abfd);
1072*fae548d3Szrj
1073*fae548d3Szrj /* PR binutils/17533: Do not allow directory traversal
1074*fae548d3Szrj outside of the current directory tree - unless the
1075*fae548d3Szrj user has explicitly specified an output directory. */
1076*fae548d3Szrj if (! is_valid_archive_path (output_filename))
1077*fae548d3Szrj {
1078*fae548d3Szrj char * base = (char *) lbasename (output_filename);
1079*fae548d3Szrj
1080*fae548d3Szrj non_fatal (_("illegal output pathname for archive member: %s, using '%s' instead"),
1081*fae548d3Szrj output_filename, base);
1082*fae548d3Szrj output_filename = base;
1083*fae548d3Szrj }
1084*fae548d3Szrj
1085*fae548d3Szrj if (output_dir)
1086*fae548d3Szrj {
1087*fae548d3Szrj size_t len = strlen (output_dir);
1088*fae548d3Szrj
1089*fae548d3Szrj if (len > 0)
1090*fae548d3Szrj {
1091*fae548d3Szrj /* FIXME: There is a memory leak here, but it is not serious. */
1092*fae548d3Szrj if (IS_DIR_SEPARATOR (output_dir [len - 1]))
1093*fae548d3Szrj output_filename = concat (output_dir, output_filename, NULL);
1094*fae548d3Szrj else
1095*fae548d3Szrj output_filename = concat (output_dir, "/", output_filename, NULL);
1096*fae548d3Szrj }
1097*fae548d3Szrj }
1098*fae548d3Szrj
1099*fae548d3Szrj if (verbose)
1100*fae548d3Szrj printf ("x - %s\n", output_filename);
1101*fae548d3Szrj
1102*fae548d3Szrj FILE * ostream = fopen (output_filename, FOPEN_WB);
1103*fae548d3Szrj if (ostream == NULL)
1104*fae548d3Szrj {
1105*fae548d3Szrj perror (output_filename);
1106*fae548d3Szrj xexit (1);
1107*fae548d3Szrj }
1108*fae548d3Szrj
1109*fae548d3Szrj return ostream;
1110*fae548d3Szrj }
1111*fae548d3Szrj
1112*fae548d3Szrj /* Extract a member of the archive into its own file.
1113*fae548d3Szrj
1114*fae548d3Szrj We defer opening the new file until after we have read a BUFSIZ chunk of the
1115*fae548d3Szrj old one, since we know we have just read the archive header for the old
1116*fae548d3Szrj one. Since most members are shorter than BUFSIZ, this means we will read
1117*fae548d3Szrj the old header, read the old data, write a new inode for the new file, and
1118*fae548d3Szrj write the new data, and be done. This 'optimization' is what comes from
1119*fae548d3Szrj sitting next to a bare disk and hearing it every time it seeks. -- Gnu
1120*fae548d3Szrj Gilmore */
1121*fae548d3Szrj
1122*fae548d3Szrj void
extract_file(bfd * abfd)1123*fae548d3Szrj extract_file (bfd *abfd)
1124*fae548d3Szrj {
1125*fae548d3Szrj bfd_size_type size;
1126*fae548d3Szrj struct stat buf;
1127*fae548d3Szrj
1128*fae548d3Szrj if (bfd_stat_arch_elt (abfd, &buf) != 0)
1129*fae548d3Szrj /* xgettext:c-format */
1130*fae548d3Szrj fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
1131*fae548d3Szrj size = buf.st_size;
1132*fae548d3Szrj
1133*fae548d3Szrj bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
1134*fae548d3Szrj
1135*fae548d3Szrj output_file = NULL;
1136*fae548d3Szrj if (size == 0)
1137*fae548d3Szrj {
1138*fae548d3Szrj output_file = open_output_file (abfd);
1139*fae548d3Szrj }
1140*fae548d3Szrj else
1141*fae548d3Szrj {
1142*fae548d3Szrj bfd_size_type ncopied = 0;
1143*fae548d3Szrj char *cbuf = (char *) xmalloc (BUFSIZE);
1144*fae548d3Szrj
1145*fae548d3Szrj while (ncopied < size)
1146*fae548d3Szrj {
1147*fae548d3Szrj bfd_size_type nread, tocopy;
1148*fae548d3Szrj
1149*fae548d3Szrj tocopy = size - ncopied;
1150*fae548d3Szrj if (tocopy > BUFSIZE)
1151*fae548d3Szrj tocopy = BUFSIZE;
1152*fae548d3Szrj
1153*fae548d3Szrj nread = bfd_bread (cbuf, tocopy, abfd);
1154*fae548d3Szrj if (nread != tocopy)
1155*fae548d3Szrj /* xgettext:c-format */
1156*fae548d3Szrj fatal (_("%s is not a valid archive"),
1157*fae548d3Szrj bfd_get_filename (abfd->my_archive));
1158*fae548d3Szrj
1159*fae548d3Szrj /* See comment above; this saves disk arm motion. */
1160*fae548d3Szrj if (output_file == NULL)
1161*fae548d3Szrj output_file = open_output_file (abfd);
1162*fae548d3Szrj
1163*fae548d3Szrj /* fwrite in mingw32 may return int instead of bfd_size_type. Cast
1164*fae548d3Szrj the return value to bfd_size_type to avoid comparison between
1165*fae548d3Szrj signed and unsigned values. */
1166*fae548d3Szrj if ((bfd_size_type) fwrite (cbuf, 1, nread, output_file) != nread)
1167*fae548d3Szrj fatal ("%s: %s", output_filename, strerror (errno));
1168*fae548d3Szrj
1169*fae548d3Szrj ncopied += tocopy;
1170*fae548d3Szrj }
1171*fae548d3Szrj
1172*fae548d3Szrj free (cbuf);
1173*fae548d3Szrj }
1174*fae548d3Szrj
1175*fae548d3Szrj fclose (output_file);
1176*fae548d3Szrj
1177*fae548d3Szrj output_file = NULL;
1178*fae548d3Szrj
1179*fae548d3Szrj chmod (output_filename, buf.st_mode);
1180*fae548d3Szrj
1181*fae548d3Szrj if (preserve_dates)
1182*fae548d3Szrj {
1183*fae548d3Szrj /* Set access time to modification time. Only st_mtime is
1184*fae548d3Szrj initialized by bfd_stat_arch_elt. */
1185*fae548d3Szrj buf.st_atime = buf.st_mtime;
1186*fae548d3Szrj set_times (output_filename, &buf);
1187*fae548d3Szrj }
1188*fae548d3Szrj
1189*fae548d3Szrj output_filename = NULL;
1190*fae548d3Szrj }
1191*fae548d3Szrj
1192*fae548d3Szrj static void
write_archive(bfd * iarch)1193*fae548d3Szrj write_archive (bfd *iarch)
1194*fae548d3Szrj {
1195*fae548d3Szrj bfd *obfd;
1196*fae548d3Szrj char *old_name, *new_name;
1197*fae548d3Szrj bfd *contents_head = iarch->archive_next;
1198*fae548d3Szrj
1199*fae548d3Szrj old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1200*fae548d3Szrj strcpy (old_name, bfd_get_filename (iarch));
1201*fae548d3Szrj new_name = make_tempname (old_name);
1202*fae548d3Szrj
1203*fae548d3Szrj if (new_name == NULL)
1204*fae548d3Szrj bfd_fatal (_("could not create temporary file whilst writing archive"));
1205*fae548d3Szrj
1206*fae548d3Szrj output_filename = new_name;
1207*fae548d3Szrj
1208*fae548d3Szrj obfd = bfd_openw (new_name, bfd_get_target (iarch));
1209*fae548d3Szrj
1210*fae548d3Szrj if (obfd == NULL)
1211*fae548d3Szrj bfd_fatal (old_name);
1212*fae548d3Szrj
1213*fae548d3Szrj output_bfd = obfd;
1214*fae548d3Szrj
1215*fae548d3Szrj bfd_set_format (obfd, bfd_archive);
1216*fae548d3Szrj
1217*fae548d3Szrj /* Request writing the archive symbol table unless we've
1218*fae548d3Szrj been explicitly requested not to. */
1219*fae548d3Szrj obfd->has_armap = write_armap >= 0;
1220*fae548d3Szrj
1221*fae548d3Szrj if (ar_truncate)
1222*fae548d3Szrj {
1223*fae548d3Szrj /* This should really use bfd_set_file_flags, but that rejects
1224*fae548d3Szrj archives. */
1225*fae548d3Szrj obfd->flags |= BFD_TRADITIONAL_FORMAT;
1226*fae548d3Szrj }
1227*fae548d3Szrj
1228*fae548d3Szrj if (deterministic)
1229*fae548d3Szrj obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1230*fae548d3Szrj
1231*fae548d3Szrj if (full_pathname)
1232*fae548d3Szrj obfd->flags |= BFD_ARCHIVE_FULL_PATH;
1233*fae548d3Szrj
1234*fae548d3Szrj if (make_thin_archive || bfd_is_thin_archive (iarch))
1235*fae548d3Szrj bfd_set_thin_archive (obfd, TRUE);
1236*fae548d3Szrj
1237*fae548d3Szrj if (!bfd_set_archive_head (obfd, contents_head))
1238*fae548d3Szrj bfd_fatal (old_name);
1239*fae548d3Szrj
1240*fae548d3Szrj if (!bfd_close (obfd))
1241*fae548d3Szrj bfd_fatal (old_name);
1242*fae548d3Szrj
1243*fae548d3Szrj output_bfd = NULL;
1244*fae548d3Szrj output_filename = NULL;
1245*fae548d3Szrj
1246*fae548d3Szrj /* We don't care if this fails; we might be creating the archive. */
1247*fae548d3Szrj bfd_close (iarch);
1248*fae548d3Szrj
1249*fae548d3Szrj if (smart_rename (new_name, old_name, 0) != 0)
1250*fae548d3Szrj xexit (1);
1251*fae548d3Szrj free (old_name);
1252*fae548d3Szrj free (new_name);
1253*fae548d3Szrj }
1254*fae548d3Szrj
1255*fae548d3Szrj /* Return a pointer to the pointer to the entry which should be rplacd'd
1256*fae548d3Szrj into when altering. DEFAULT_POS should be how to interpret pos_default,
1257*fae548d3Szrj and should be a pos value. */
1258*fae548d3Szrj
1259*fae548d3Szrj static bfd **
get_pos_bfd(bfd ** contents,enum pos default_pos,const char * default_posname)1260*fae548d3Szrj get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1261*fae548d3Szrj {
1262*fae548d3Szrj bfd **after_bfd = contents;
1263*fae548d3Szrj enum pos realpos;
1264*fae548d3Szrj const char *realposname;
1265*fae548d3Szrj
1266*fae548d3Szrj if (postype == pos_default)
1267*fae548d3Szrj {
1268*fae548d3Szrj realpos = default_pos;
1269*fae548d3Szrj realposname = default_posname;
1270*fae548d3Szrj }
1271*fae548d3Szrj else
1272*fae548d3Szrj {
1273*fae548d3Szrj realpos = postype;
1274*fae548d3Szrj realposname = posname;
1275*fae548d3Szrj }
1276*fae548d3Szrj
1277*fae548d3Szrj if (realpos == pos_end)
1278*fae548d3Szrj {
1279*fae548d3Szrj while (*after_bfd)
1280*fae548d3Szrj after_bfd = &((*after_bfd)->archive_next);
1281*fae548d3Szrj }
1282*fae548d3Szrj else
1283*fae548d3Szrj {
1284*fae548d3Szrj for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
1285*fae548d3Szrj if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1286*fae548d3Szrj {
1287*fae548d3Szrj if (realpos == pos_after)
1288*fae548d3Szrj after_bfd = &(*after_bfd)->archive_next;
1289*fae548d3Szrj break;
1290*fae548d3Szrj }
1291*fae548d3Szrj }
1292*fae548d3Szrj return after_bfd;
1293*fae548d3Szrj }
1294*fae548d3Szrj
1295*fae548d3Szrj static void
delete_members(bfd * arch,char ** files_to_delete)1296*fae548d3Szrj delete_members (bfd *arch, char **files_to_delete)
1297*fae548d3Szrj {
1298*fae548d3Szrj bfd **current_ptr_ptr;
1299*fae548d3Szrj bfd_boolean found;
1300*fae548d3Szrj bfd_boolean something_changed = FALSE;
1301*fae548d3Szrj int match_count;
1302*fae548d3Szrj
1303*fae548d3Szrj for (; *files_to_delete != NULL; ++files_to_delete)
1304*fae548d3Szrj {
1305*fae548d3Szrj /* In a.out systems, the armap is optional. It's also called
1306*fae548d3Szrj __.SYMDEF. So if the user asked to delete it, we should remember
1307*fae548d3Szrj that fact. This isn't quite right for COFF systems (where
1308*fae548d3Szrj __.SYMDEF might be regular member), but it's very unlikely
1309*fae548d3Szrj to be a problem. FIXME */
1310*fae548d3Szrj
1311*fae548d3Szrj if (!strcmp (*files_to_delete, "__.SYMDEF"))
1312*fae548d3Szrj {
1313*fae548d3Szrj arch->has_armap = FALSE;
1314*fae548d3Szrj write_armap = -1;
1315*fae548d3Szrj continue;
1316*fae548d3Szrj }
1317*fae548d3Szrj
1318*fae548d3Szrj found = FALSE;
1319*fae548d3Szrj match_count = 0;
1320*fae548d3Szrj current_ptr_ptr = &(arch->archive_next);
1321*fae548d3Szrj while (*current_ptr_ptr)
1322*fae548d3Szrj {
1323*fae548d3Szrj if (FILENAME_CMP (normalize (*files_to_delete, arch),
1324*fae548d3Szrj (*current_ptr_ptr)->filename) == 0)
1325*fae548d3Szrj {
1326*fae548d3Szrj ++match_count;
1327*fae548d3Szrj if (counted_name_mode
1328*fae548d3Szrj && match_count != counted_name_counter)
1329*fae548d3Szrj {
1330*fae548d3Szrj /* Counting, and didn't match on count; go on to the
1331*fae548d3Szrj next one. */
1332*fae548d3Szrj }
1333*fae548d3Szrj else
1334*fae548d3Szrj {
1335*fae548d3Szrj found = TRUE;
1336*fae548d3Szrj something_changed = TRUE;
1337*fae548d3Szrj if (verbose)
1338*fae548d3Szrj printf ("d - %s\n",
1339*fae548d3Szrj *files_to_delete);
1340*fae548d3Szrj *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
1341*fae548d3Szrj goto next_file;
1342*fae548d3Szrj }
1343*fae548d3Szrj }
1344*fae548d3Szrj
1345*fae548d3Szrj current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1346*fae548d3Szrj }
1347*fae548d3Szrj
1348*fae548d3Szrj if (verbose && !found)
1349*fae548d3Szrj {
1350*fae548d3Szrj /* xgettext:c-format */
1351*fae548d3Szrj printf (_("No member named `%s'\n"), *files_to_delete);
1352*fae548d3Szrj }
1353*fae548d3Szrj next_file:
1354*fae548d3Szrj ;
1355*fae548d3Szrj }
1356*fae548d3Szrj
1357*fae548d3Szrj if (something_changed)
1358*fae548d3Szrj write_archive (arch);
1359*fae548d3Szrj else
1360*fae548d3Szrj output_filename = NULL;
1361*fae548d3Szrj }
1362*fae548d3Szrj
1363*fae548d3Szrj
1364*fae548d3Szrj /* Reposition existing members within an archive */
1365*fae548d3Szrj
1366*fae548d3Szrj static void
move_members(bfd * arch,char ** files_to_move)1367*fae548d3Szrj move_members (bfd *arch, char **files_to_move)
1368*fae548d3Szrj {
1369*fae548d3Szrj bfd **after_bfd; /* New entries go after this one */
1370*fae548d3Szrj bfd **current_ptr_ptr; /* cdr pointer into contents */
1371*fae548d3Szrj
1372*fae548d3Szrj for (; *files_to_move; ++files_to_move)
1373*fae548d3Szrj {
1374*fae548d3Szrj current_ptr_ptr = &(arch->archive_next);
1375*fae548d3Szrj while (*current_ptr_ptr)
1376*fae548d3Szrj {
1377*fae548d3Szrj bfd *current_ptr = *current_ptr_ptr;
1378*fae548d3Szrj if (FILENAME_CMP (normalize (*files_to_move, arch),
1379*fae548d3Szrj current_ptr->filename) == 0)
1380*fae548d3Szrj {
1381*fae548d3Szrj /* Move this file to the end of the list - first cut from
1382*fae548d3Szrj where it is. */
1383*fae548d3Szrj bfd *link_bfd;
1384*fae548d3Szrj *current_ptr_ptr = current_ptr->archive_next;
1385*fae548d3Szrj
1386*fae548d3Szrj /* Now glue to end */
1387*fae548d3Szrj after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1388*fae548d3Szrj link_bfd = *after_bfd;
1389*fae548d3Szrj *after_bfd = current_ptr;
1390*fae548d3Szrj current_ptr->archive_next = link_bfd;
1391*fae548d3Szrj
1392*fae548d3Szrj if (verbose)
1393*fae548d3Szrj printf ("m - %s\n", *files_to_move);
1394*fae548d3Szrj
1395*fae548d3Szrj goto next_file;
1396*fae548d3Szrj }
1397*fae548d3Szrj
1398*fae548d3Szrj current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1399*fae548d3Szrj }
1400*fae548d3Szrj /* xgettext:c-format */
1401*fae548d3Szrj fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1402*fae548d3Szrj
1403*fae548d3Szrj next_file:;
1404*fae548d3Szrj }
1405*fae548d3Szrj
1406*fae548d3Szrj write_archive (arch);
1407*fae548d3Szrj }
1408*fae548d3Szrj
1409*fae548d3Szrj /* Ought to default to replacing in place, but this is existing practice! */
1410*fae548d3Szrj
1411*fae548d3Szrj static void
replace_members(bfd * arch,char ** files_to_move,bfd_boolean quick)1412*fae548d3Szrj replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
1413*fae548d3Szrj {
1414*fae548d3Szrj bfd_boolean changed = FALSE;
1415*fae548d3Szrj bfd **after_bfd; /* New entries go after this one. */
1416*fae548d3Szrj bfd *current;
1417*fae548d3Szrj bfd **current_ptr;
1418*fae548d3Szrj
1419*fae548d3Szrj while (files_to_move && *files_to_move)
1420*fae548d3Szrj {
1421*fae548d3Szrj if (! quick)
1422*fae548d3Szrj {
1423*fae548d3Szrj current_ptr = &arch->archive_next;
1424*fae548d3Szrj while (*current_ptr)
1425*fae548d3Szrj {
1426*fae548d3Szrj current = *current_ptr;
1427*fae548d3Szrj
1428*fae548d3Szrj /* For compatibility with existing ar programs, we
1429*fae548d3Szrj permit the same file to be added multiple times. */
1430*fae548d3Szrj if (FILENAME_CMP (normalize (*files_to_move, arch),
1431*fae548d3Szrj normalize (current->filename, arch)) == 0
1432*fae548d3Szrj && current->arelt_data != NULL)
1433*fae548d3Szrj {
1434*fae548d3Szrj if (newer_only)
1435*fae548d3Szrj {
1436*fae548d3Szrj struct stat fsbuf, asbuf;
1437*fae548d3Szrj
1438*fae548d3Szrj if (stat (*files_to_move, &fsbuf) != 0)
1439*fae548d3Szrj {
1440*fae548d3Szrj if (errno != ENOENT)
1441*fae548d3Szrj bfd_fatal (*files_to_move);
1442*fae548d3Szrj goto next_file;
1443*fae548d3Szrj }
1444*fae548d3Szrj if (bfd_stat_arch_elt (current, &asbuf) != 0)
1445*fae548d3Szrj /* xgettext:c-format */
1446*fae548d3Szrj fatal (_("internal stat error on %s"),
1447*fae548d3Szrj current->filename);
1448*fae548d3Szrj
1449*fae548d3Szrj if (fsbuf.st_mtime <= asbuf.st_mtime)
1450*fae548d3Szrj goto next_file;
1451*fae548d3Szrj }
1452*fae548d3Szrj
1453*fae548d3Szrj after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
1454*fae548d3Szrj current->filename);
1455*fae548d3Szrj if (ar_emul_replace (after_bfd, *files_to_move,
1456*fae548d3Szrj target, verbose))
1457*fae548d3Szrj {
1458*fae548d3Szrj /* Snip out this entry from the chain. */
1459*fae548d3Szrj *current_ptr = (*current_ptr)->archive_next;
1460*fae548d3Szrj changed = TRUE;
1461*fae548d3Szrj }
1462*fae548d3Szrj
1463*fae548d3Szrj goto next_file;
1464*fae548d3Szrj }
1465*fae548d3Szrj current_ptr = &(current->archive_next);
1466*fae548d3Szrj }
1467*fae548d3Szrj }
1468*fae548d3Szrj
1469*fae548d3Szrj /* Add to the end of the archive. */
1470*fae548d3Szrj after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1471*fae548d3Szrj
1472*fae548d3Szrj if (ar_emul_append (after_bfd, *files_to_move, target,
1473*fae548d3Szrj verbose, make_thin_archive))
1474*fae548d3Szrj changed = TRUE;
1475*fae548d3Szrj
1476*fae548d3Szrj next_file:;
1477*fae548d3Szrj
1478*fae548d3Szrj files_to_move++;
1479*fae548d3Szrj }
1480*fae548d3Szrj
1481*fae548d3Szrj if (changed)
1482*fae548d3Szrj write_archive (arch);
1483*fae548d3Szrj else
1484*fae548d3Szrj output_filename = NULL;
1485*fae548d3Szrj }
1486*fae548d3Szrj
1487*fae548d3Szrj static int
ranlib_only(const char * archname)1488*fae548d3Szrj ranlib_only (const char *archname)
1489*fae548d3Szrj {
1490*fae548d3Szrj bfd *arch;
1491*fae548d3Szrj
1492*fae548d3Szrj if (get_file_size (archname) < 1)
1493*fae548d3Szrj return 1;
1494*fae548d3Szrj write_armap = 1;
1495*fae548d3Szrj arch = open_inarch (archname, (char *) NULL);
1496*fae548d3Szrj if (arch == NULL)
1497*fae548d3Szrj xexit (1);
1498*fae548d3Szrj write_archive (arch);
1499*fae548d3Szrj return 0;
1500*fae548d3Szrj }
1501*fae548d3Szrj
1502*fae548d3Szrj /* Update the timestamp of the symbol map of an archive. */
1503*fae548d3Szrj
1504*fae548d3Szrj static int
ranlib_touch(const char * archname)1505*fae548d3Szrj ranlib_touch (const char *archname)
1506*fae548d3Szrj {
1507*fae548d3Szrj #ifdef __GO32__
1508*fae548d3Szrj /* I don't think updating works on go32. */
1509*fae548d3Szrj ranlib_only (archname);
1510*fae548d3Szrj #else
1511*fae548d3Szrj int f;
1512*fae548d3Szrj bfd *arch;
1513*fae548d3Szrj char **matching;
1514*fae548d3Szrj
1515*fae548d3Szrj if (get_file_size (archname) < 1)
1516*fae548d3Szrj return 1;
1517*fae548d3Szrj f = open (archname, O_RDWR | O_BINARY, 0);
1518*fae548d3Szrj if (f < 0)
1519*fae548d3Szrj {
1520*fae548d3Szrj bfd_set_error (bfd_error_system_call);
1521*fae548d3Szrj bfd_fatal (archname);
1522*fae548d3Szrj }
1523*fae548d3Szrj
1524*fae548d3Szrj arch = bfd_fdopenr (archname, (const char *) NULL, f);
1525*fae548d3Szrj if (arch == NULL)
1526*fae548d3Szrj bfd_fatal (archname);
1527*fae548d3Szrj if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1528*fae548d3Szrj {
1529*fae548d3Szrj bfd_nonfatal (archname);
1530*fae548d3Szrj if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1531*fae548d3Szrj {
1532*fae548d3Szrj list_matching_formats (matching);
1533*fae548d3Szrj free (matching);
1534*fae548d3Szrj }
1535*fae548d3Szrj xexit (1);
1536*fae548d3Szrj }
1537*fae548d3Szrj
1538*fae548d3Szrj if (! bfd_has_map (arch))
1539*fae548d3Szrj /* xgettext:c-format */
1540*fae548d3Szrj fatal (_("%s: no archive map to update"), archname);
1541*fae548d3Szrj
1542*fae548d3Szrj if (deterministic)
1543*fae548d3Szrj arch->flags |= BFD_DETERMINISTIC_OUTPUT;
1544*fae548d3Szrj
1545*fae548d3Szrj bfd_update_armap_timestamp (arch);
1546*fae548d3Szrj
1547*fae548d3Szrj if (! bfd_close (arch))
1548*fae548d3Szrj bfd_fatal (archname);
1549*fae548d3Szrj #endif
1550*fae548d3Szrj return 0;
1551*fae548d3Szrj }
1552*fae548d3Szrj
1553*fae548d3Szrj /* Things which are interesting to map over all or some of the files: */
1554*fae548d3Szrj
1555*fae548d3Szrj static void
print_descr(bfd * abfd)1556*fae548d3Szrj print_descr (bfd *abfd)
1557*fae548d3Szrj {
1558*fae548d3Szrj print_arelt_descr (stdout, abfd, verbose, display_offsets);
1559*fae548d3Szrj }
1560