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