xref: /netbsd/external/gpl3/gdb.old/dist/binutils/ar.c (revision 56bb7041)
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