12159047fSniklas /* bucomm.c -- Bin Utils COMmon code. 2b55d4692Sfgsch Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001 3b305b0f1Sespie Free Software Foundation, Inc. 42159047fSniklas 52159047fSniklas This file is part of GNU Binutils. 62159047fSniklas 72159047fSniklas This program is free software; you can redistribute it and/or modify 82159047fSniklas it under the terms of the GNU General Public License as published by 92159047fSniklas the Free Software Foundation; either version 2 of the License, or 102159047fSniklas (at your option) any later version. 112159047fSniklas 122159047fSniklas This program is distributed in the hope that it will be useful, 132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of 142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 152159047fSniklas GNU General Public License for more details. 162159047fSniklas 172159047fSniklas You should have received a copy of the GNU General Public License 182159047fSniklas along with this program; if not, write to the Free Software 19b305b0f1Sespie Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20b305b0f1Sespie 02111-1307, USA. */ 212159047fSniklas 222159047fSniklas /* We might put this in a library someday so it could be dynamically 232159047fSniklas loaded, but for now it's not necessary. */ 242159047fSniklas 252159047fSniklas #include "bfd.h" 262159047fSniklas #include "libiberty.h" 272159047fSniklas #include "bucomm.h" 28b305b0f1Sespie #include "filenames.h" 292159047fSniklas 302159047fSniklas #include <sys/stat.h> 312159047fSniklas #include <time.h> /* ctime, maybe time_t */ 322159047fSniklas 332159047fSniklas #ifndef HAVE_TIME_T_IN_TIME_H 342159047fSniklas #ifndef HAVE_TIME_T_IN_TYPES_H 352159047fSniklas typedef long time_t; 362159047fSniklas #endif 372159047fSniklas #endif 382159047fSniklas 392159047fSniklas /* Error reporting */ 402159047fSniklas 412159047fSniklas char *program_name; 422159047fSniklas 432159047fSniklas void 442159047fSniklas bfd_nonfatal (string) 452159047fSniklas CONST char *string; 462159047fSniklas { 472159047fSniklas CONST char *errmsg = bfd_errmsg (bfd_get_error ()); 482159047fSniklas 492159047fSniklas if (string) 502159047fSniklas fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg); 512159047fSniklas else 522159047fSniklas fprintf (stderr, "%s: %s\n", program_name, errmsg); 532159047fSniklas } 542159047fSniklas 552159047fSniklas void 562159047fSniklas bfd_fatal (string) 572159047fSniklas CONST char *string; 582159047fSniklas { 592159047fSniklas bfd_nonfatal (string); 602159047fSniklas xexit (1); 612159047fSniklas } 622159047fSniklas 63b305b0f1Sespie void 64b305b0f1Sespie report (format, args) 65b305b0f1Sespie const char * format; 66b305b0f1Sespie va_list args; 67b305b0f1Sespie { 68b305b0f1Sespie fprintf (stderr, "%s: ", program_name); 69b305b0f1Sespie vfprintf (stderr, format, args); 70b305b0f1Sespie putc ('\n', stderr); 71b305b0f1Sespie } 72b305b0f1Sespie 732159047fSniklas #ifdef ANSI_PROTOTYPES 742159047fSniklas void 752159047fSniklas fatal (const char *format, ...) 762159047fSniklas { 772159047fSniklas va_list args; 782159047fSniklas 792159047fSniklas va_start (args, format); 80b305b0f1Sespie report (format, args); 812159047fSniklas va_end (args); 822159047fSniklas xexit (1); 832159047fSniklas } 84b305b0f1Sespie 85b305b0f1Sespie void 86b305b0f1Sespie non_fatal (const char *format, ...) 87b305b0f1Sespie { 88b305b0f1Sespie va_list args; 89b305b0f1Sespie 90b305b0f1Sespie va_start (args, format); 91b305b0f1Sespie report (format, args); 92b305b0f1Sespie va_end (args); 93b305b0f1Sespie } 942159047fSniklas #else 952159047fSniklas void 962159047fSniklas fatal (va_alist) 972159047fSniklas va_dcl 982159047fSniklas { 992159047fSniklas char *Format; 1002159047fSniklas va_list args; 1012159047fSniklas 1022159047fSniklas va_start (args); 1032159047fSniklas Format = va_arg (args, char *); 104b305b0f1Sespie report (Format, args); 1052159047fSniklas va_end (args); 1062159047fSniklas xexit (1); 1072159047fSniklas } 108b305b0f1Sespie 109b305b0f1Sespie void 110b305b0f1Sespie non_fatal (va_alist) 111b305b0f1Sespie va_dcl 112b305b0f1Sespie { 113b305b0f1Sespie char *Format; 114b305b0f1Sespie va_list args; 115b305b0f1Sespie 116b305b0f1Sespie va_start (args); 117b305b0f1Sespie Format = va_arg (args, char *); 118b305b0f1Sespie report (Format, args); 119b305b0f1Sespie va_end (args); 120b305b0f1Sespie } 1212159047fSniklas #endif 1222159047fSniklas 123b305b0f1Sespie /* Set the default BFD target based on the configured target. Doing 124b305b0f1Sespie this permits the binutils to be configured for a particular target, 125b305b0f1Sespie and linked against a shared BFD library which was configured for a 126b305b0f1Sespie different target. */ 127b305b0f1Sespie 128b305b0f1Sespie void 129b305b0f1Sespie set_default_bfd_target () 130b305b0f1Sespie { 131b305b0f1Sespie /* The macro TARGET is defined by Makefile. */ 132b305b0f1Sespie const char *target = TARGET; 133b305b0f1Sespie 134b305b0f1Sespie if (! bfd_set_default_target (target)) 135b305b0f1Sespie fatal (_("can't set BFD default target to `%s': %s"), 136b305b0f1Sespie target, bfd_errmsg (bfd_get_error ())); 137b305b0f1Sespie } 138b305b0f1Sespie 1392159047fSniklas /* After a false return from bfd_check_format_matches with 140b305b0f1Sespie bfd_get_error () == bfd_error_file_ambiguously_recognized, print 141b305b0f1Sespie the possible matching targets. */ 1422159047fSniklas 1432159047fSniklas void 1442159047fSniklas list_matching_formats (p) 1452159047fSniklas char **p; 1462159047fSniklas { 147b305b0f1Sespie fprintf (stderr, _("%s: Matching formats:"), program_name); 1482159047fSniklas while (*p) 1492159047fSniklas fprintf (stderr, " %s", *p++); 150b305b0f1Sespie fputc ('\n', stderr); 1512159047fSniklas } 1522159047fSniklas 1532159047fSniklas /* List the supported targets. */ 1542159047fSniklas 1552159047fSniklas void 1562159047fSniklas list_supported_targets (name, f) 1572159047fSniklas const char *name; 1582159047fSniklas FILE *f; 1592159047fSniklas { 160b55d4692Sfgsch extern const bfd_target *const *bfd_target_vector; 1612159047fSniklas int t; 1622159047fSniklas 1632159047fSniklas if (name == NULL) 164b305b0f1Sespie fprintf (f, _("Supported targets:")); 1652159047fSniklas else 166b305b0f1Sespie fprintf (f, _("%s: supported targets:"), name); 1672159047fSniklas for (t = 0; bfd_target_vector[t] != NULL; t++) 1682159047fSniklas fprintf (f, " %s", bfd_target_vector[t]->name); 1692159047fSniklas fprintf (f, "\n"); 1702159047fSniklas } 1712159047fSniklas 1722159047fSniklas /* Display the archive header for an element as if it were an ls -l listing: 1732159047fSniklas 1742159047fSniklas Mode User\tGroup\tSize\tDate Name */ 1752159047fSniklas 1762159047fSniklas void 1772159047fSniklas print_arelt_descr (file, abfd, verbose) 1782159047fSniklas FILE *file; 1792159047fSniklas bfd *abfd; 1802159047fSniklas boolean verbose; 1812159047fSniklas { 1822159047fSniklas struct stat buf; 1832159047fSniklas 1842159047fSniklas if (verbose) 1852159047fSniklas { 1862159047fSniklas if (bfd_stat_arch_elt (abfd, &buf) == 0) 1872159047fSniklas { 1882159047fSniklas char modebuf[11]; 1892159047fSniklas char timebuf[40]; 1902159047fSniklas time_t when = buf.st_mtime; 1912159047fSniklas CONST char *ctime_result = (CONST char *) ctime (&when); 1922159047fSniklas 1932159047fSniklas /* POSIX format: skip weekday and seconds from ctime output. */ 1942159047fSniklas sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20); 1952159047fSniklas 1962159047fSniklas mode_string (buf.st_mode, modebuf); 1972159047fSniklas modebuf[10] = '\0'; 1982159047fSniklas /* POSIX 1003.2/D11 says to skip first character (entry type). */ 1992159047fSniklas fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1, 2002159047fSniklas (long) buf.st_uid, (long) buf.st_gid, 2012159047fSniklas (long) buf.st_size, timebuf); 2022159047fSniklas } 2032159047fSniklas } 2042159047fSniklas 2052159047fSniklas fprintf (file, "%s\n", bfd_get_filename (abfd)); 2062159047fSniklas } 2072159047fSniklas 208b305b0f1Sespie /* Return the name of a temporary file in the same directory as FILENAME. */ 2092159047fSniklas 2102159047fSniklas char * 2119a986918Sespie make_tempname (filename, isdir) 2122159047fSniklas char *filename; 2139a986918Sespie int isdir; 2142159047fSniklas { 215b305b0f1Sespie static char template[] = "stXXXXXX"; 2162159047fSniklas char *tmpname; 2172159047fSniklas char *slash = strrchr (filename, '/'); 2189a986918Sespie char c; 2192159047fSniklas 220b305b0f1Sespie #ifdef HAVE_DOS_BASED_FILE_SYSTEM 221b305b0f1Sespie { 222b305b0f1Sespie /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ 223b305b0f1Sespie char *bslash = strrchr (filename, '\\'); 2249a986918Sespie 225b55d4692Sfgsch if (slash == NULL || (bslash != NULL && bslash > slash)) 226b305b0f1Sespie slash = bslash; 227b305b0f1Sespie if (slash == NULL && filename[0] != '\0' && filename[1] == ':') 228b305b0f1Sespie slash = filename + 1; 229b305b0f1Sespie } 230b305b0f1Sespie #endif 231b305b0f1Sespie 2322159047fSniklas if (slash != (char *) NULL) 2332159047fSniklas { 234b305b0f1Sespie c = *slash; 2352159047fSniklas *slash = 0; 236b305b0f1Sespie tmpname = xmalloc (strlen (filename) + sizeof (template) + 2); 2372159047fSniklas strcpy (tmpname, filename); 238b305b0f1Sespie #ifdef HAVE_DOS_BASED_FILE_SYSTEM 239b305b0f1Sespie /* If tmpname is "X:", appending a slash will make it a root 240b305b0f1Sespie directory on drive X, which is NOT the same as the current 241b305b0f1Sespie directory on drive X. */ 242b305b0f1Sespie if (tmpname[1] == ':' && tmpname[2] == '\0') 243b305b0f1Sespie strcat (tmpname, "."); 244b305b0f1Sespie #endif 2452159047fSniklas strcat (tmpname, "/"); 2462159047fSniklas strcat (tmpname, template); 2472159047fSniklas } 2482159047fSniklas else 2492159047fSniklas { 2502159047fSniklas tmpname = xmalloc (sizeof (template)); 2512159047fSniklas strcpy (tmpname, template); 2522159047fSniklas } 2539a986918Sespie 2549a986918Sespie if (isdir) 2559a986918Sespie { 2569a986918Sespie #ifdef HAVE_MKDTEMP 257*3d4065ffSespie if (mkdtemp (tmpname) == (char *) NULL) 2589a986918Sespie #else 2599a986918Sespie mktemp (tmpname); 2609a986918Sespie #if defined (_WIN32) && !defined (__CYGWIN32__) 2619a986918Sespie if (mkdir (tmpname) != 0) 2629a986918Sespie #else 2639a986918Sespie if (mkdir (tmpname, 0700) != 0) 2649a986918Sespie #endif 2659a986918Sespie #endif 2669a986918Sespie tmpname = NULL; 2679a986918Sespie } 2689a986918Sespie else 2699a986918Sespie { 2709a986918Sespie int fd; 2719a986918Sespie 2729a986918Sespie #ifdef HAVE_MKSTEMP 2739a986918Sespie fd = mkstemp (tmpname); 2749a986918Sespie if (fd == -1) 2759a986918Sespie tmpname = NULL; 2769a986918Sespie else 2779a986918Sespie close (fd); 2789a986918Sespie #else 2799a986918Sespie mktemp (tmpname); 2809a986918Sespie #endif 2819a986918Sespie } 2829a986918Sespie if (slash != (char *) NULL) 2839a986918Sespie *slash = c; 2849a986918Sespie 2852159047fSniklas return tmpname; 2862159047fSniklas } 2872159047fSniklas 2882159047fSniklas /* Parse a string into a VMA, with a fatal error if it can't be 2892159047fSniklas parsed. */ 2902159047fSniklas 2912159047fSniklas bfd_vma 2922159047fSniklas parse_vma (s, arg) 2932159047fSniklas const char *s; 2942159047fSniklas const char *arg; 2952159047fSniklas { 2962159047fSniklas bfd_vma ret; 2972159047fSniklas const char *end; 2982159047fSniklas 2992159047fSniklas ret = bfd_scan_vma (s, &end, 0); 300b305b0f1Sespie 3012159047fSniklas if (*end != '\0') 302b305b0f1Sespie fatal (_("%s: bad number: %s"), arg, s); 303b305b0f1Sespie 3042159047fSniklas return ret; 3052159047fSniklas } 306