Change sources over to using GPLv3
[deliverable/binutils-gdb.git] / binutils / arsup.c
CommitLineData
252b5132 1/* arsup.c - Archive support for MRI compatibility
aef6203b 2 Copyright 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
3db64b00 3 2004, 2007 Free Software Foundation, Inc.
252b5132 4
3a1a2036 5 This file is part of GNU Binutils.
252b5132 6
3a1a2036
NC
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
32866df7 9 the Free Software Foundation; either version 3 of the License, or
3a1a2036 10 (at your option) any later version.
252b5132 11
3a1a2036
NC
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
252b5132 16
3a1a2036
NC
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
32866df7
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132
RH
21
22
23/* Contributed by Steve Chamberlain
3a1a2036 24 sac@cygnus.com
252b5132 25
3a1a2036
NC
26 This file looks after requests from arparse.y, to provide the MRI
27 style librarian command syntax + 1 word LIST. */
252b5132 28
3db64b00 29#include "sysdep.h"
252b5132 30#include "bfd.h"
252b5132 31#include "libiberty.h"
5af11cab 32#include "filenames.h"
3db64b00
AM
33#include "bucomm.h"
34#include "arsup.h"
252b5132
RH
35
36static void map_over_list
2da42df6
AJ
37 (bfd *, void (*function) (bfd *, bfd *), struct list *);
38static void ar_directory_doer (bfd *, bfd *);
39static void ar_addlib_doer (bfd *, bfd *);
252b5132
RH
40
41extern int verbose;
42
85b1c36d
BE
43static bfd *obfd;
44static char *real_name;
45static FILE *outfile;
46
252b5132 47static void
2da42df6 48map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list)
252b5132
RH
49{
50 bfd *head;
51
52 if (list == NULL)
53 {
54 bfd *next;
55
cc481421 56 head = arch->archive_next;
252b5132
RH
57 while (head != NULL)
58 {
cc481421 59 next = head->archive_next;
252b5132
RH
60 function (head, (bfd *) NULL);
61 head = next;
62 }
63 }
64 else
65 {
66 struct list *ptr;
67
68 /* This may appear to be a baroque way of accomplishing what we
69 want. however we have to iterate over the filenames in order
70 to notice where a filename is requested but does not exist in
71 the archive. Ditto mapping over each file each time -- we
72 want to hack multiple references. */
73 for (ptr = list; ptr; ptr = ptr->next)
74 {
b34976b6 75 bfd_boolean found = FALSE;
252b5132
RH
76 bfd *prev = arch;
77
cc481421 78 for (head = arch->archive_next; head; head = head->archive_next)
252b5132
RH
79 {
80 if (head->filename != NULL
5af11cab 81 && FILENAME_CMP (ptr->name, head->filename) == 0)
252b5132 82 {
b34976b6 83 found = TRUE;
252b5132
RH
84 function (head, prev);
85 }
86 prev = head;
87 }
88 if (! found)
89 fprintf (stderr, _("No entry %s in archive.\n"), ptr->name);
90 }
91 }
92}
93
94
252b5132 95
252b5132 96static void
2da42df6 97ar_directory_doer (bfd *abfd, bfd *ignore ATTRIBUTE_UNUSED)
252b5132 98{
3a1a2036 99 print_arelt_descr(outfile, abfd, verbose);
252b5132
RH
100}
101
102void
2da42df6 103ar_directory (char *ar_name, struct list *list, char *output)
252b5132
RH
104{
105 bfd *arch;
106
107 arch = open_inarch (ar_name, (char *) NULL);
108 if (output)
109 {
110 outfile = fopen(output,"w");
111 if (outfile == 0)
112 {
113 outfile = stdout;
114 fprintf (stderr,_("Can't open file %s\n"), output);
115 output = 0;
116 }
117 }
f462a9ea 118 else
252b5132
RH
119 outfile = stdout;
120
121 map_over_list (arch, ar_directory_doer, list);
122
123 bfd_close (arch);
124
125 if (output)
126 fclose (outfile);
127}
128
129void
2da42df6 130prompt (void)
252b5132
RH
131{
132 extern int interactive;
3a1a2036 133
f462a9ea 134 if (interactive)
3a1a2036
NC
135 {
136 printf ("AR >");
137 fflush (stdout);
138 }
252b5132
RH
139}
140
141void
2da42df6 142maybequit (void)
252b5132 143{
f462a9ea 144 if (! interactive)
252b5132
RH
145 xexit (9);
146}
147
148
3a1a2036 149void
2da42df6 150ar_open (char *name, int t)
252b5132
RH
151{
152 char *tname = (char *) xmalloc (strlen (name) + 10);
5e9520c8 153 const char *bname = lbasename (name);
252b5132 154 real_name = name;
3a1a2036 155
5af11cab
AM
156 /* Prepend tmp- to the beginning, to avoid file-name clashes after
157 truncation on filesystems with limited namespaces (DOS). */
3a1a2036
NC
158 sprintf (tname, "%.*stmp-%s", (int) (bname - name), name, bname);
159 obfd = bfd_openw (tname, NULL);
160
161 if (!obfd)
162 {
163 fprintf (stderr,
164 _("%s: Can't open output archive %s\n"),
165 program_name, tname);
166
167 maybequit ();
252b5132 168 }
3a1a2036
NC
169 else
170 {
171 if (!t)
172 {
173 bfd **ptr;
174 bfd *element;
175 bfd *ibfd;
252b5132 176
3a1a2036 177 ibfd = bfd_openr (name, NULL);
252b5132 178
3a1a2036
NC
179 if (!ibfd)
180 {
181 fprintf (stderr,_("%s: Can't open input archive %s\n"),
182 program_name, name);
183 maybequit ();
184 return;
185 }
186
b34976b6 187 if (!bfd_check_format(ibfd, bfd_archive))
3a1a2036
NC
188 {
189 fprintf (stderr,
190 _("%s: file %s is not an archive\n"),
191 program_name, name);
192 maybequit ();
193 return;
194 }
195
196 ptr = &(obfd->archive_head);
197 element = bfd_openr_next_archived_file (ibfd, NULL);
198
199 while (element)
200 {
201 *ptr = element;
cc481421 202 ptr = &element->archive_next;
3a1a2036
NC
203 element = bfd_openr_next_archived_file (ibfd, element);
204 }
205 }
206
207 bfd_set_format (obfd, bfd_archive);
252b5132 208
3a1a2036
NC
209 obfd->has_armap = 1;
210 }
211}
252b5132
RH
212
213static void
2da42df6 214ar_addlib_doer (bfd *abfd, bfd *prev)
252b5132 215{
3a1a2036 216 /* Add this module to the output bfd. */
252b5132 217 if (prev != NULL)
cc481421 218 prev->archive_next = abfd->archive_next;
3a1a2036 219
cc481421 220 abfd->archive_next = obfd->archive_head;
252b5132
RH
221 obfd->archive_head = abfd;
222}
223
224void
2da42df6 225ar_addlib (char *name, struct list *list)
252b5132
RH
226{
227 if (obfd == NULL)
228 {
229 fprintf (stderr, _("%s: no output archive specified yet\n"), program_name);
230 maybequit ();
231 }
232 else
233 {
234 bfd *arch;
235
236 arch = open_inarch (name, (char *) NULL);
237 if (arch != NULL)
238 map_over_list (arch, ar_addlib_doer, list);
239
50c2245b 240 /* Don't close the bfd, since it will make the elements disappear. */
252b5132
RH
241 }
242}
243
244void
2da42df6 245ar_addmod (struct list *list)
252b5132 246{
3a1a2036
NC
247 if (!obfd)
248 {
249 fprintf (stderr, _("%s: no open output archive\n"), program_name);
250 maybequit ();
251 }
f462a9ea 252 else
3a1a2036
NC
253 {
254 while (list)
255 {
256 bfd *abfd = bfd_openr (list->name, NULL);
257
258 if (!abfd)
259 {
260 fprintf (stderr, _("%s: can't open file %s\n"),
261 program_name, list->name);
262 maybequit ();
263 }
264 else
265 {
cc481421 266 abfd->archive_next = obfd->archive_head;
3a1a2036
NC
267 obfd->archive_head = abfd;
268 }
269 list = list->next;
270 }
252b5132 271 }
252b5132
RH
272}
273
274
252b5132 275void
2da42df6 276ar_clear (void)
252b5132 277{
3a1a2036
NC
278 if (obfd)
279 obfd->archive_head = 0;
252b5132
RH
280}
281
282void
2da42df6 283ar_delete (struct list *list)
252b5132 284{
3a1a2036
NC
285 if (!obfd)
286 {
287 fprintf (stderr, _("%s: no open output archive\n"), program_name);
288 maybequit ();
289 }
f462a9ea 290 else
3a1a2036
NC
291 {
292 while (list)
293 {
294 /* Find this name in the archive. */
295 bfd *member = obfd->archive_head;
296 bfd **prev = &(obfd->archive_head);
297 int found = 0;
298
299 while (member)
300 {
301 if (FILENAME_CMP(member->filename, list->name) == 0)
302 {
cc481421 303 *prev = member->archive_next;
3a1a2036
NC
304 found = 1;
305 }
306 else
cc481421 307 prev = &(member->archive_next);
3a1a2036 308
cc481421 309 member = member->archive_next;
3a1a2036
NC
310 }
311
312 if (!found)
313 {
314 fprintf (stderr, _("%s: can't find module file %s\n"),
315 program_name, list->name);
316 maybequit ();
317 }
318
319 list = list->next;
252b5132 320 }
252b5132 321 }
252b5132
RH
322}
323
252b5132 324void
2da42df6 325ar_save (void)
252b5132 326{
3a1a2036
NC
327 if (!obfd)
328 {
329 fprintf (stderr, _("%s: no open output archive\n"), program_name);
330 maybequit ();
331 }
332 else
333 {
334 char *ofilename = xstrdup (bfd_get_filename (obfd));
252b5132 335
3a1a2036 336 bfd_close (obfd);
252b5132 337
1ba93119 338 smart_rename (ofilename, real_name, 0);
3a1a2036
NC
339 obfd = 0;
340 free (ofilename);
341 }
342}
252b5132
RH
343
344void
2da42df6 345ar_replace (struct list *list)
252b5132 346{
3a1a2036
NC
347 if (!obfd)
348 {
349 fprintf (stderr, _("%s: no open output archive\n"), program_name);
350 maybequit ();
351 }
f462a9ea 352 else
3a1a2036
NC
353 {
354 while (list)
252b5132 355 {
3a1a2036
NC
356 /* Find this name in the archive. */
357 bfd *member = obfd->archive_head;
358 bfd **prev = &(obfd->archive_head);
359 int found = 0;
360
361 while (member)
362 {
363 if (FILENAME_CMP (member->filename, list->name) == 0)
364 {
365 /* Found the one to replace. */
366 bfd *abfd = bfd_openr (list->name, 0);
367
368 if (!abfd)
369 {
370 fprintf (stderr, _("%s: can't open file %s\n"),
371 program_name, list->name);
372 maybequit ();
373 }
374 else
375 {
376 *prev = abfd;
cc481421 377 abfd->archive_next = member->archive_next;
3a1a2036
NC
378 found = 1;
379 }
380 }
381 else
382 {
cc481421 383 prev = &(member->archive_next);
3a1a2036 384 }
cc481421 385 member = member->archive_next;
3a1a2036
NC
386 }
387
388 if (!found)
389 {
390 bfd *abfd = bfd_openr (list->name, 0);
252b5132 391
3a1a2036
NC
392 fprintf (stderr,_("%s: can't find module file %s\n"),
393 program_name, list->name);
394 if (!abfd)
395 {
396 fprintf (stderr, _("%s: can't open file %s\n"),
397 program_name, list->name);
398 maybequit ();
399 }
400 else
401 *prev = abfd;
402 }
403
404 list = list->next;
405 }
252b5132 406 }
252b5132
RH
407}
408
3a1a2036 409/* And I added this one. */
252b5132 410void
2da42df6 411ar_list (void)
252b5132 412{
f462a9ea 413 if (!obfd)
252b5132 414 {
3a1a2036
NC
415 fprintf (stderr, _("%s: no open output archive\n"), program_name);
416 maybequit ();
252b5132 417 }
3a1a2036
NC
418 else
419 {
420 bfd *abfd;
421
422 outfile = stdout;
423 verbose =1 ;
424 printf (_("Current open archive is %s\n"), bfd_get_filename (obfd));
252b5132 425
3a1a2036
NC
426 for (abfd = obfd->archive_head;
427 abfd != (bfd *)NULL;
cc481421 428 abfd = abfd->archive_next)
3a1a2036
NC
429 ar_directory_doer (abfd, (bfd *) NULL);
430 }
431}
252b5132 432
f462a9ea 433void
2da42df6 434ar_end (void)
252b5132
RH
435{
436 if (obfd)
3a1a2036 437 {
c92c35e7 438 bfd_cache_close (obfd);
3a1a2036
NC
439 unlink (bfd_get_filename (obfd));
440 }
252b5132 441}
3a1a2036 442
252b5132 443void
2da42df6 444ar_extract (struct list *list)
252b5132 445{
f462a9ea 446 if (!obfd)
3a1a2036
NC
447 {
448 fprintf (stderr, _("%s: no open archive\n"), program_name);
449 maybequit ();
450 }
f462a9ea 451 else
3a1a2036
NC
452 {
453 while (list)
252b5132 454 {
3a1a2036
NC
455 /* Find this name in the archive. */
456 bfd *member = obfd->archive_head;
457 int found = 0;
458
459 while (member && !found)
460 {
461 if (FILENAME_CMP (member->filename, list->name) == 0)
462 {
463 extract_file (member);
464 found = 1;
465 }
466
cc481421 467 member = member->archive_next;
3a1a2036
NC
468 }
469
470 if (!found)
471 {
472 bfd_openr (list->name, 0);
473 fprintf (stderr, _("%s: can't find module file %s\n"),
474 program_name, list->name);
475 }
476
477 list = list->next;
478 }
252b5132 479 }
252b5132 480}
This page took 0.323266 seconds and 4 git commands to generate.