13d8817e4Smiod /* bucomm.c -- Bin Utils COMmon code.
23d8817e4Smiod Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2003
33d8817e4Smiod Free Software Foundation, Inc.
43d8817e4Smiod
53d8817e4Smiod This file is part of GNU Binutils.
63d8817e4Smiod
73d8817e4Smiod This program is free software; you can redistribute it and/or modify
83d8817e4Smiod it under the terms of the GNU General Public License as published by
93d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
103d8817e4Smiod (at your option) any later version.
113d8817e4Smiod
123d8817e4Smiod This program is distributed in the hope that it will be useful,
133d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
143d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
153d8817e4Smiod GNU General Public License for more details.
163d8817e4Smiod
173d8817e4Smiod You should have received a copy of the GNU General Public License
183d8817e4Smiod along with this program; if not, write to the Free Software
193d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
203d8817e4Smiod 02110-1301, USA. */
213d8817e4Smiod
223d8817e4Smiod /* We might put this in a library someday so it could be dynamically
233d8817e4Smiod loaded, but for now it's not necessary. */
243d8817e4Smiod
253d8817e4Smiod #include "bfd.h"
263d8817e4Smiod #include "bfdver.h"
273d8817e4Smiod #include "libiberty.h"
283d8817e4Smiod #include "bucomm.h"
293d8817e4Smiod #include "filenames.h"
303d8817e4Smiod #include "libbfd.h"
313d8817e4Smiod
323d8817e4Smiod #include <sys/stat.h>
333d8817e4Smiod #include <time.h> /* ctime, maybe time_t */
343d8817e4Smiod #include <assert.h>
353d8817e4Smiod
363d8817e4Smiod #ifndef HAVE_TIME_T_IN_TIME_H
373d8817e4Smiod #ifndef HAVE_TIME_T_IN_TYPES_H
383d8817e4Smiod typedef long time_t;
393d8817e4Smiod #endif
403d8817e4Smiod #endif
413d8817e4Smiod
423d8817e4Smiod static const char * endian_string (enum bfd_endian);
433d8817e4Smiod static int display_target_list (void);
443d8817e4Smiod static int display_info_table (int, int);
453d8817e4Smiod static int display_target_tables (void);
463d8817e4Smiod
473d8817e4Smiod /* Error reporting. */
483d8817e4Smiod
493d8817e4Smiod char *program_name;
503d8817e4Smiod
513d8817e4Smiod void
bfd_nonfatal(const char * string)523d8817e4Smiod bfd_nonfatal (const char *string)
533d8817e4Smiod {
543d8817e4Smiod const char *errmsg = bfd_errmsg (bfd_get_error ());
553d8817e4Smiod
563d8817e4Smiod if (string)
573d8817e4Smiod fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg);
583d8817e4Smiod else
593d8817e4Smiod fprintf (stderr, "%s: %s\n", program_name, errmsg);
603d8817e4Smiod }
613d8817e4Smiod
623d8817e4Smiod void
bfd_fatal(const char * string)633d8817e4Smiod bfd_fatal (const char *string)
643d8817e4Smiod {
653d8817e4Smiod bfd_nonfatal (string);
663d8817e4Smiod xexit (1);
673d8817e4Smiod }
683d8817e4Smiod
693d8817e4Smiod void
report(const char * format,va_list args)703d8817e4Smiod report (const char * format, va_list args)
713d8817e4Smiod {
723d8817e4Smiod fprintf (stderr, "%s: ", program_name);
733d8817e4Smiod vfprintf (stderr, format, args);
743d8817e4Smiod putc ('\n', stderr);
753d8817e4Smiod }
763d8817e4Smiod
773d8817e4Smiod void
fatal(const char * format,...)783d8817e4Smiod fatal VPARAMS ((const char *format, ...))
793d8817e4Smiod {
803d8817e4Smiod VA_OPEN (args, format);
813d8817e4Smiod VA_FIXEDARG (args, const char *, format);
823d8817e4Smiod
833d8817e4Smiod report (format, args);
843d8817e4Smiod VA_CLOSE (args);
853d8817e4Smiod xexit (1);
863d8817e4Smiod }
873d8817e4Smiod
883d8817e4Smiod void
non_fatal(const char * format,...)893d8817e4Smiod non_fatal VPARAMS ((const char *format, ...))
903d8817e4Smiod {
913d8817e4Smiod VA_OPEN (args, format);
923d8817e4Smiod VA_FIXEDARG (args, const char *, format);
933d8817e4Smiod
943d8817e4Smiod report (format, args);
953d8817e4Smiod VA_CLOSE (args);
963d8817e4Smiod }
973d8817e4Smiod
983d8817e4Smiod /* Set the default BFD target based on the configured target. Doing
993d8817e4Smiod this permits the binutils to be configured for a particular target,
1003d8817e4Smiod and linked against a shared BFD library which was configured for a
1013d8817e4Smiod different target. */
1023d8817e4Smiod
1033d8817e4Smiod void
set_default_bfd_target(void)1043d8817e4Smiod set_default_bfd_target (void)
1053d8817e4Smiod {
1063d8817e4Smiod /* The macro TARGET is defined by Makefile. */
1073d8817e4Smiod const char *target = TARGET;
1083d8817e4Smiod
1093d8817e4Smiod if (! bfd_set_default_target (target))
1103d8817e4Smiod fatal (_("can't set BFD default target to `%s': %s"),
1113d8817e4Smiod target, bfd_errmsg (bfd_get_error ()));
1123d8817e4Smiod }
1133d8817e4Smiod
1143d8817e4Smiod /* After a FALSE return from bfd_check_format_matches with
1153d8817e4Smiod bfd_get_error () == bfd_error_file_ambiguously_recognized, print
1163d8817e4Smiod the possible matching targets. */
1173d8817e4Smiod
1183d8817e4Smiod void
list_matching_formats(char ** p)1193d8817e4Smiod list_matching_formats (char **p)
1203d8817e4Smiod {
1213d8817e4Smiod fprintf (stderr, _("%s: Matching formats:"), program_name);
1223d8817e4Smiod while (*p)
1233d8817e4Smiod fprintf (stderr, " %s", *p++);
1243d8817e4Smiod fputc ('\n', stderr);
1253d8817e4Smiod }
1263d8817e4Smiod
1273d8817e4Smiod /* List the supported targets. */
1283d8817e4Smiod
1293d8817e4Smiod void
list_supported_targets(const char * name,FILE * f)1303d8817e4Smiod list_supported_targets (const char *name, FILE *f)
1313d8817e4Smiod {
1323d8817e4Smiod int t;
1333d8817e4Smiod const char **targ_names = bfd_target_list ();
1343d8817e4Smiod
1353d8817e4Smiod if (name == NULL)
1363d8817e4Smiod fprintf (f, _("Supported targets:"));
1373d8817e4Smiod else
1383d8817e4Smiod fprintf (f, _("%s: supported targets:"), name);
1393d8817e4Smiod
1403d8817e4Smiod for (t = 0; targ_names[t] != NULL; t++)
1413d8817e4Smiod fprintf (f, " %s", targ_names[t]);
1423d8817e4Smiod fprintf (f, "\n");
1433d8817e4Smiod free (targ_names);
1443d8817e4Smiod }
1453d8817e4Smiod
1463d8817e4Smiod /* List the supported architectures. */
1473d8817e4Smiod
1483d8817e4Smiod void
list_supported_architectures(const char * name,FILE * f)1493d8817e4Smiod list_supported_architectures (const char *name, FILE *f)
1503d8817e4Smiod {
1513d8817e4Smiod const char **arch;
1523d8817e4Smiod
1533d8817e4Smiod if (name == NULL)
1543d8817e4Smiod fprintf (f, _("Supported architectures:"));
1553d8817e4Smiod else
1563d8817e4Smiod fprintf (f, _("%s: supported architectures:"), name);
1573d8817e4Smiod
1583d8817e4Smiod for (arch = bfd_arch_list (); *arch; arch++)
1593d8817e4Smiod fprintf (f, " %s", *arch);
1603d8817e4Smiod fprintf (f, "\n");
1613d8817e4Smiod }
1623d8817e4Smiod
1633d8817e4Smiod /* The length of the longest architecture name + 1. */
1643d8817e4Smiod #define LONGEST_ARCH sizeof ("powerpc:common")
1653d8817e4Smiod
1663d8817e4Smiod static const char *
endian_string(enum bfd_endian endian)1673d8817e4Smiod endian_string (enum bfd_endian endian)
1683d8817e4Smiod {
1693d8817e4Smiod switch (endian)
1703d8817e4Smiod {
1713d8817e4Smiod case BFD_ENDIAN_BIG: return "big endian";
1723d8817e4Smiod case BFD_ENDIAN_LITTLE: return "little endian";
1733d8817e4Smiod default: return "endianness unknown";
1743d8817e4Smiod }
1753d8817e4Smiod }
1763d8817e4Smiod
1773d8817e4Smiod /* List the targets that BFD is configured to support, each followed
1783d8817e4Smiod by its endianness and the architectures it supports. */
1793d8817e4Smiod
1803d8817e4Smiod static int
display_target_list(void)1813d8817e4Smiod display_target_list (void)
1823d8817e4Smiod {
1833d8817e4Smiod char *dummy_name;
1843d8817e4Smiod int t;
1853d8817e4Smiod int ret = 1;
1863d8817e4Smiod
1873d8817e4Smiod dummy_name = make_temp_file (NULL);
1883d8817e4Smiod for (t = 0; bfd_target_vector[t]; t++)
1893d8817e4Smiod {
1903d8817e4Smiod const bfd_target *p = bfd_target_vector[t];
1913d8817e4Smiod bfd *abfd = bfd_openw (dummy_name, p->name);
1923d8817e4Smiod enum bfd_architecture a;
1933d8817e4Smiod
1943d8817e4Smiod printf ("%s\n (header %s, data %s)\n", p->name,
1953d8817e4Smiod endian_string (p->header_byteorder),
1963d8817e4Smiod endian_string (p->byteorder));
1973d8817e4Smiod
1983d8817e4Smiod if (abfd == NULL)
1993d8817e4Smiod {
2003d8817e4Smiod bfd_nonfatal (dummy_name);
2013d8817e4Smiod ret = 0;
2023d8817e4Smiod continue;
2033d8817e4Smiod }
2043d8817e4Smiod
2053d8817e4Smiod if (! bfd_set_format (abfd, bfd_object))
2063d8817e4Smiod {
2073d8817e4Smiod if (bfd_get_error () != bfd_error_invalid_operation)
2083d8817e4Smiod {
2093d8817e4Smiod bfd_nonfatal (p->name);
2103d8817e4Smiod ret = 0;
2113d8817e4Smiod }
2123d8817e4Smiod bfd_close_all_done (abfd);
2133d8817e4Smiod continue;
2143d8817e4Smiod }
2153d8817e4Smiod
2163d8817e4Smiod for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
2173d8817e4Smiod if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
2183d8817e4Smiod printf (" %s\n",
2193d8817e4Smiod bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
2203d8817e4Smiod bfd_close_all_done (abfd);
2213d8817e4Smiod }
2223d8817e4Smiod unlink (dummy_name);
2233d8817e4Smiod free (dummy_name);
2243d8817e4Smiod
2253d8817e4Smiod return ret;
2263d8817e4Smiod }
2273d8817e4Smiod
2283d8817e4Smiod /* Print a table showing which architectures are supported for entries
2293d8817e4Smiod FIRST through LAST-1 of bfd_target_vector (targets across,
2303d8817e4Smiod architectures down). */
2313d8817e4Smiod
2323d8817e4Smiod static int
display_info_table(int first,int last)2333d8817e4Smiod display_info_table (int first, int last)
2343d8817e4Smiod {
2353d8817e4Smiod int t;
2363d8817e4Smiod int ret = 1;
2373d8817e4Smiod char *dummy_name;
2383d8817e4Smiod enum bfd_architecture a;
2393d8817e4Smiod
2403d8817e4Smiod /* Print heading of target names. */
2413d8817e4Smiod printf ("\n%*s", (int) LONGEST_ARCH, " ");
2423d8817e4Smiod for (t = first; t < last && bfd_target_vector[t]; t++)
2433d8817e4Smiod printf ("%s ", bfd_target_vector[t]->name);
2443d8817e4Smiod putchar ('\n');
2453d8817e4Smiod
2463d8817e4Smiod dummy_name = make_temp_file (NULL);
2473d8817e4Smiod for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
2483d8817e4Smiod if (strcmp (bfd_printable_arch_mach (a, 0), "UNKNOWN!") != 0)
2493d8817e4Smiod {
2503d8817e4Smiod printf ("%*s ", (int) LONGEST_ARCH - 1,
2513d8817e4Smiod bfd_printable_arch_mach (a, 0));
2523d8817e4Smiod for (t = first; t < last && bfd_target_vector[t]; t++)
2533d8817e4Smiod {
2543d8817e4Smiod const bfd_target *p = bfd_target_vector[t];
2553d8817e4Smiod bfd_boolean ok = TRUE;
2563d8817e4Smiod bfd *abfd = bfd_openw (dummy_name, p->name);
2573d8817e4Smiod
2583d8817e4Smiod if (abfd == NULL)
2593d8817e4Smiod {
2603d8817e4Smiod bfd_nonfatal (p->name);
2613d8817e4Smiod ret = 0;
2623d8817e4Smiod ok = FALSE;
2633d8817e4Smiod }
2643d8817e4Smiod
2653d8817e4Smiod if (ok)
2663d8817e4Smiod {
2673d8817e4Smiod if (! bfd_set_format (abfd, bfd_object))
2683d8817e4Smiod {
2693d8817e4Smiod if (bfd_get_error () != bfd_error_invalid_operation)
2703d8817e4Smiod {
2713d8817e4Smiod bfd_nonfatal (p->name);
2723d8817e4Smiod ret = 0;
2733d8817e4Smiod }
2743d8817e4Smiod ok = FALSE;
2753d8817e4Smiod }
2763d8817e4Smiod }
2773d8817e4Smiod
2783d8817e4Smiod if (ok)
2793d8817e4Smiod {
2803d8817e4Smiod if (! bfd_set_arch_mach (abfd, a, 0))
2813d8817e4Smiod ok = FALSE;
2823d8817e4Smiod }
2833d8817e4Smiod
2843d8817e4Smiod if (ok)
2853d8817e4Smiod printf ("%s ", p->name);
2863d8817e4Smiod else
2873d8817e4Smiod {
2883d8817e4Smiod int l = strlen (p->name);
2893d8817e4Smiod while (l--)
2903d8817e4Smiod putchar ('-');
2913d8817e4Smiod putchar (' ');
2923d8817e4Smiod }
2933d8817e4Smiod if (abfd != NULL)
2943d8817e4Smiod bfd_close_all_done (abfd);
2953d8817e4Smiod }
2963d8817e4Smiod putchar ('\n');
2973d8817e4Smiod }
2983d8817e4Smiod unlink (dummy_name);
2993d8817e4Smiod free (dummy_name);
3003d8817e4Smiod
3013d8817e4Smiod return ret;
3023d8817e4Smiod }
3033d8817e4Smiod
3043d8817e4Smiod /* Print tables of all the target-architecture combinations that
3053d8817e4Smiod BFD has been configured to support. */
3063d8817e4Smiod
3073d8817e4Smiod static int
display_target_tables(void)3083d8817e4Smiod display_target_tables (void)
3093d8817e4Smiod {
3103d8817e4Smiod int t;
3113d8817e4Smiod int columns;
3123d8817e4Smiod int ret = 1;
3133d8817e4Smiod char *colum;
3143d8817e4Smiod
3153d8817e4Smiod columns = 0;
3163d8817e4Smiod colum = getenv ("COLUMNS");
3173d8817e4Smiod if (colum != NULL)
3183d8817e4Smiod columns = atoi (colum);
3193d8817e4Smiod if (columns == 0)
3203d8817e4Smiod columns = 80;
3213d8817e4Smiod
3223d8817e4Smiod t = 0;
3233d8817e4Smiod while (bfd_target_vector[t] != NULL)
3243d8817e4Smiod {
3253d8817e4Smiod int oldt = t, wid;
3263d8817e4Smiod
3273d8817e4Smiod wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
3283d8817e4Smiod ++t;
3293d8817e4Smiod while (wid < columns && bfd_target_vector[t] != NULL)
3303d8817e4Smiod {
3313d8817e4Smiod int newwid;
3323d8817e4Smiod
3333d8817e4Smiod newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
3343d8817e4Smiod if (newwid >= columns)
3353d8817e4Smiod break;
3363d8817e4Smiod wid = newwid;
3373d8817e4Smiod ++t;
3383d8817e4Smiod }
3393d8817e4Smiod if (! display_info_table (oldt, t))
3403d8817e4Smiod ret = 0;
3413d8817e4Smiod }
3423d8817e4Smiod
3433d8817e4Smiod return ret;
3443d8817e4Smiod }
3453d8817e4Smiod
3463d8817e4Smiod int
display_info(void)3473d8817e4Smiod display_info (void)
3483d8817e4Smiod {
3493d8817e4Smiod printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
3503d8817e4Smiod if (! display_target_list () || ! display_target_tables ())
3513d8817e4Smiod return 1;
3523d8817e4Smiod else
3533d8817e4Smiod return 0;
3543d8817e4Smiod }
3553d8817e4Smiod
3563d8817e4Smiod /* Display the archive header for an element as if it were an ls -l listing:
3573d8817e4Smiod
3583d8817e4Smiod Mode User\tGroup\tSize\tDate Name */
3593d8817e4Smiod
3603d8817e4Smiod void
print_arelt_descr(FILE * file,bfd * abfd,bfd_boolean verbose)3613d8817e4Smiod print_arelt_descr (FILE *file, bfd *abfd, bfd_boolean verbose)
3623d8817e4Smiod {
3633d8817e4Smiod struct stat buf;
3643d8817e4Smiod
3653d8817e4Smiod if (verbose)
3663d8817e4Smiod {
3673d8817e4Smiod if (bfd_stat_arch_elt (abfd, &buf) == 0)
3683d8817e4Smiod {
3693d8817e4Smiod char modebuf[11];
3703d8817e4Smiod char timebuf[40];
3713d8817e4Smiod time_t when = buf.st_mtime;
3723d8817e4Smiod const char *ctime_result = (const char *) ctime (&when);
3733d8817e4Smiod
3743d8817e4Smiod /* POSIX format: skip weekday and seconds from ctime output. */
3753d8817e4Smiod sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20);
3763d8817e4Smiod
3773d8817e4Smiod mode_string (buf.st_mode, modebuf);
3783d8817e4Smiod modebuf[10] = '\0';
3793d8817e4Smiod /* POSIX 1003.2/D11 says to skip first character (entry type). */
3803d8817e4Smiod fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1,
3813d8817e4Smiod (long) buf.st_uid, (long) buf.st_gid,
3823d8817e4Smiod (long) buf.st_size, timebuf);
3833d8817e4Smiod }
3843d8817e4Smiod }
3853d8817e4Smiod
3863d8817e4Smiod fprintf (file, "%s\n", bfd_get_filename (abfd));
3873d8817e4Smiod }
3883d8817e4Smiod
3893d8817e4Smiod /* Return the name of a temporary file in the same directory as FILENAME. */
3903d8817e4Smiod
3913d8817e4Smiod char *
make_tempname(char * filename,int isdir)392d2386abeSmiod make_tempname (char *filename, int isdir)
3933d8817e4Smiod {
3943d8817e4Smiod static char template[] = "stXXXXXX";
3953d8817e4Smiod char *tmpname;
3963d8817e4Smiod char *slash = strrchr (filename, '/');
397*e2674b3fSdrahn char c = '/';
3983d8817e4Smiod
3993d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4003d8817e4Smiod {
4013d8817e4Smiod /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */
4023d8817e4Smiod char *bslash = strrchr (filename, '\\');
4033d8817e4Smiod if (slash == NULL || (bslash != NULL && bslash > slash))
4043d8817e4Smiod slash = bslash;
4053d8817e4Smiod if (slash == NULL && filename[0] != '\0' && filename[1] == ':')
4063d8817e4Smiod slash = filename + 1;
4073d8817e4Smiod }
4083d8817e4Smiod #endif
4093d8817e4Smiod
4103d8817e4Smiod if (slash != (char *) NULL)
4113d8817e4Smiod {
4123d8817e4Smiod c = *slash;
4133d8817e4Smiod *slash = 0;
4143d8817e4Smiod tmpname = xmalloc (strlen (filename) + sizeof (template) + 2);
4153d8817e4Smiod strcpy (tmpname, filename);
4163d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4173d8817e4Smiod /* If tmpname is "X:", appending a slash will make it a root
4183d8817e4Smiod directory on drive X, which is NOT the same as the current
4193d8817e4Smiod directory on drive X. */
4203d8817e4Smiod if (tmpname[1] == ':' && tmpname[2] == '\0')
4213d8817e4Smiod strcat (tmpname, ".");
4223d8817e4Smiod #endif
4233d8817e4Smiod strcat (tmpname, "/");
4243d8817e4Smiod strcat (tmpname, template);
4253d8817e4Smiod }
4263d8817e4Smiod else
4273d8817e4Smiod {
4283d8817e4Smiod tmpname = xmalloc (sizeof (template));
4293d8817e4Smiod strcpy (tmpname, template);
4303d8817e4Smiod }
431d2386abeSmiod
432d2386abeSmiod if (isdir)
433d2386abeSmiod {
434d2386abeSmiod if (mkdtemp (tmpname) == (char *) NULL)
435d2386abeSmiod tmpname = NULL;
436d2386abeSmiod }
437d2386abeSmiod else
438d2386abeSmiod {
439d2386abeSmiod int fd;
440d2386abeSmiod
441d2386abeSmiod fd = mkstemp (tmpname);
442d2386abeSmiod if (fd == -1)
443d2386abeSmiod tmpname = NULL;
444d2386abeSmiod else
445d2386abeSmiod close (fd);
446d2386abeSmiod }
447d2386abeSmiod if (slash != (char *) NULL)
448d2386abeSmiod *slash = c;
449d2386abeSmiod
4503d8817e4Smiod return tmpname;
4513d8817e4Smiod }
4523d8817e4Smiod
4533d8817e4Smiod /* Parse a string into a VMA, with a fatal error if it can't be
4543d8817e4Smiod parsed. */
4553d8817e4Smiod
4563d8817e4Smiod bfd_vma
parse_vma(const char * s,const char * arg)4573d8817e4Smiod parse_vma (const char *s, const char *arg)
4583d8817e4Smiod {
4593d8817e4Smiod bfd_vma ret;
4603d8817e4Smiod const char *end;
4613d8817e4Smiod
4623d8817e4Smiod ret = bfd_scan_vma (s, &end, 0);
4633d8817e4Smiod
4643d8817e4Smiod if (*end != '\0')
4653d8817e4Smiod fatal (_("%s: bad number: %s"), arg, s);
4663d8817e4Smiod
4673d8817e4Smiod return ret;
4683d8817e4Smiod }
4693d8817e4Smiod
4703d8817e4Smiod /* Returns the size of the named file. If the file does not
4713d8817e4Smiod exist, or if it is not a real file, then a suitable non-fatal
4723d8817e4Smiod error message is printed and zero is returned. */
4733d8817e4Smiod
4743d8817e4Smiod off_t
get_file_size(const char * file_name)4753d8817e4Smiod get_file_size (const char * file_name)
4763d8817e4Smiod {
4773d8817e4Smiod struct stat statbuf;
4783d8817e4Smiod
4793d8817e4Smiod if (stat (file_name, &statbuf) < 0)
4803d8817e4Smiod {
4813d8817e4Smiod if (errno == ENOENT)
4823d8817e4Smiod non_fatal (_("'%s': No such file"), file_name);
4833d8817e4Smiod else
4843d8817e4Smiod non_fatal (_("Warning: could not locate '%s'. reason: %s"),
4853d8817e4Smiod file_name, strerror (errno));
4863d8817e4Smiod }
4873d8817e4Smiod else if (! S_ISREG (statbuf.st_mode))
4883d8817e4Smiod non_fatal (_("Warning: '%s' is not an ordinary file"), file_name);
4893d8817e4Smiod else
4903d8817e4Smiod return statbuf.st_size;
4913d8817e4Smiod
4923d8817e4Smiod return 0;
4933d8817e4Smiod }
4943d8817e4Smiod
4953d8817e4Smiod /* Return the filename in a static buffer. */
4963d8817e4Smiod
4973d8817e4Smiod const char *
bfd_get_archive_filename(bfd * abfd)4983d8817e4Smiod bfd_get_archive_filename (bfd *abfd)
4993d8817e4Smiod {
5003d8817e4Smiod static size_t curr = 0;
5013d8817e4Smiod static char *buf;
5023d8817e4Smiod size_t needed;
5033d8817e4Smiod
5043d8817e4Smiod assert (abfd != NULL);
5053d8817e4Smiod
5063d8817e4Smiod if (!abfd->my_archive)
5073d8817e4Smiod return bfd_get_filename (abfd);
5083d8817e4Smiod
5093d8817e4Smiod needed = (strlen (bfd_get_filename (abfd->my_archive))
5103d8817e4Smiod + strlen (bfd_get_filename (abfd)) + 3);
5113d8817e4Smiod if (needed > curr)
5123d8817e4Smiod {
5133d8817e4Smiod if (curr)
5143d8817e4Smiod free (buf);
5153d8817e4Smiod curr = needed + (needed >> 1);
5163d8817e4Smiod buf = bfd_malloc (curr);
5173d8817e4Smiod /* If we can't malloc, fail safe by returning just the file name.
5183d8817e4Smiod This function is only used when building error messages. */
5193d8817e4Smiod if (!buf)
5203d8817e4Smiod {
5213d8817e4Smiod curr = 0;
5223d8817e4Smiod return bfd_get_filename (abfd);
5233d8817e4Smiod }
5243d8817e4Smiod }
5253d8817e4Smiod sprintf (buf, "%s(%s)", bfd_get_filename (abfd->my_archive),
5263d8817e4Smiod bfd_get_filename (abfd));
5273d8817e4Smiod return buf;
5283d8817e4Smiod }
529