xref: /openbsd/gnu/usr.bin/binutils/binutils/bucomm.c (revision 3d4065ff)
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