/* Low-level I/O routines for BFDs.

   Copyright (C) 1990-2023 Free Software Foundation, Inc.

   Written by Cygnus Support.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "aout/ar.h"
#if defined (_WIN32)
#include <windows.h>
#include <locale.h>
#endif

#ifndef S_IXUSR
#define S_IXUSR 0100    /* Execute by owner.  */
#endif
#ifndef S_IXGRP
#define S_IXGRP 0010    /* Execute by group.  */
#endif
#ifndef S_IXOTH
#define S_IXOTH 0001    /* Execute by others.  */
#endif

#ifndef FD_CLOEXEC
#define FD_CLOEXEC 1
#endif

file_ptr
_bfd_real_ftell (FILE *file)
{
#if defined (HAVE_FTELLO64)
  return ftello64 (file);
#elif defined (HAVE_FTELLO)
  return ftello (file);
#else
  return ftell (file);
#endif
}

int
_bfd_real_fseek (FILE *file, file_ptr offset, int whence)
{
#if defined (HAVE_FSEEKO64)
  return fseeko64 (file, offset, whence);
#elif defined (HAVE_FSEEKO)
  return fseeko (file, offset, whence);
#else
  return fseek (file, offset, whence);
#endif
}

/* Mark FILE as close-on-exec.  Return FILE.  FILE may be NULL, in
   which case nothing is done.  */
static FILE *
close_on_exec (FILE *file)
{
#if defined (HAVE_FILENO) && defined (F_GETFD)
  if (file)
    {
      int fd = fileno (file);
      int old = fcntl (fd, F_GETFD, 0);
      if (old >= 0)
	fcntl (fd, F_SETFD, old | FD_CLOEXEC);
    }
#endif
  return file;
}

FILE *
_bfd_real_fopen (const char *filename, const char *modes)
{
#ifdef VMS
  char *vms_attr;

  /* On VMS, fopen allows file attributes as optional arguments.
     We need to use them but we'd better to use the common prototype.
     In fopen-vms.h, they are separated from the mode with a comma.
     Split here.  */
  vms_attr = strchr (modes, ',');
  if (vms_attr != NULL)
    {
      /* Attributes found.  Split.  */
      size_t modes_len = strlen (modes) + 1;
      char attrs[modes_len + 1];
      char *at[3];
      int i;

      memcpy (attrs, modes, modes_len);
      at[0] = attrs;
      for (i = 0; i < 2; i++)
	{
	  at[i + 1] = strchr (at[i], ',');
	  BFD_ASSERT (at[i + 1] != NULL);
	  *(at[i + 1]++) = 0; /* Replace ',' with a nul, and skip it.  */
	}
      return close_on_exec (fopen (filename, at[0], at[1], at[2]));
    }

#elif defined (_WIN32)
  /* PR 25713: Handle extra long path names possibly containing '..' and '.'.  */
   wchar_t **     lpFilePart = {NULL};
   const wchar_t  prefix[] = L"\\\\?\\";
   const size_t   partPathLen = strlen (filename) + 1;
#ifdef __MINGW32__
#if !HAVE_DECL____LC_CODEPAGE_FUNC
/* This prototype was added to locale.h in version 9.0 of MinGW-w64.  */
   _CRTIMP unsigned int __cdecl ___lc_codepage_func (void);
#endif
   const unsigned int cp = ___lc_codepage_func ();
#else
   const unsigned int cp = CP_UTF8;
#endif

   /* Converting the partial path from ascii to unicode.
      1) Get the length: Calling with lpWideCharStr set to null returns the length.
      2) Convert the string: Calling with cbMultiByte set to -1 includes the terminating null.  */
   size_t         partPathWSize = MultiByteToWideChar (cp, 0, filename, -1, NULL, 0);
   wchar_t *      partPath = calloc (partPathWSize, sizeof(wchar_t));
   size_t         ix;

   MultiByteToWideChar (cp, 0, filename, -1, partPath, partPathWSize);

   /* Convert any UNIX style path separators into the DOS i.e. backslash separator.  */
   for (ix = 0; ix < partPathLen; ix++)
     if (IS_UNIX_DIR_SEPARATOR(filename[ix]))
       partPath[ix] = '\\';

   /* Getting the full path from the provided partial path.
      1) Get the length.
      2) Resolve the path.  */
   long       fullPathWSize = GetFullPathNameW (partPath, 0, NULL, lpFilePart);
   wchar_t *  fullPath = calloc (fullPathWSize + sizeof(prefix) + 1, sizeof(wchar_t));

   wcscpy (fullPath, prefix);

   int        prefixLen = sizeof(prefix) / sizeof(wchar_t);

   /* Do not add a prefix to the null device.  */
   if (stricmp (filename, "nul") == 0)
    prefixLen = 1;

   wchar_t *  fullPathOffset = fullPath + prefixLen - 1;

   GetFullPathNameW (partPath, fullPathWSize, fullPathOffset, lpFilePart);
   free (partPath);

   /* It is non-standard for modes to exceed 16 characters.  */
   wchar_t    modesW[16];

   MultiByteToWideChar (cp, 0, modes, -1, modesW, sizeof(modesW));

   FILE *     file = _wfopen (fullPath, modesW);
   free (fullPath);

   return close_on_exec (file);

#elif defined (HAVE_FOPEN64)
  return close_on_exec (fopen64 (filename, modes));

#else
  return close_on_exec (fopen (filename, modes));
#endif
}

/*
INTERNAL_DEFINITION
	struct bfd_iovec

DESCRIPTION

	The <<struct bfd_iovec>> contains the internal file I/O class.
	Each <<BFD>> has an instance of this class and all file I/O is
	routed through it (it is assumed that the instance implements
	all methods listed below).

.struct bfd_iovec
.{
.  {* To avoid problems with macros, a "b" rather than "f"
.     prefix is prepended to each method name.  *}
.  {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
.     bytes starting at PTR.  Return the number of bytes actually
.     transfered (a read past end-of-file returns less than NBYTES),
.     or -1 (setting <<bfd_error>>) if an error occurs.  *}
.  file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
.  file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
.		       file_ptr nbytes);
.  {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
.     if an error occurs.  *}
.  file_ptr (*btell) (struct bfd *abfd);
.  {* For the following, on successful completion a value of 0 is returned.
.     Otherwise, a value of -1 is returned (and <<bfd_error>> is set).  *}
.  int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
.  int (*bclose) (struct bfd *abfd);
.  int (*bflush) (struct bfd *abfd);
.  int (*bstat) (struct bfd *abfd, struct stat *sb);
.  {* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
.     mmap parameter, except that LEN and OFFSET do not need to be page
.     aligned.  Returns (void *)-1 on failure, mmapped address on success.
.     Also write in MAP_ADDR the address of the page aligned buffer and in
.     MAP_LEN the size mapped (a page multiple).  Use unmap with MAP_ADDR and
.     MAP_LEN to unmap.  *}
.  void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
.		   int prot, int flags, file_ptr offset,
.		   void **map_addr, bfd_size_type *map_len);
.};

.extern const struct bfd_iovec _bfd_memory_iovec;
.
*/


/*
FUNCTION
	bfd_read

SYNOPSIS
	bfd_size_type bfd_read (void *, bfd_size_type, bfd *)
				ATTRIBUTE_WARN_UNUSED_RESULT;

DESCRIPTION
	Attempt to read SIZE bytes from ABFD's iostream to PTR.
	Return the amount read.
*/

bfd_size_type
bfd_read (void *ptr, bfd_size_type size, bfd *abfd)
{
  file_ptr nread;
  bfd *element_bfd = abfd;
  ufile_ptr offset = 0;

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    {
      offset += abfd->origin;
      abfd = abfd->my_archive;
    }
  offset += abfd->origin;

  /* If this is a non-thin archive element, don't read past the end of
     this element.  */
  if (element_bfd->arelt_data != NULL
      && element_bfd->my_archive != NULL
      && !bfd_is_thin_archive (element_bfd->my_archive))
    {
      bfd_size_type maxbytes = arelt_size (element_bfd);

      if (abfd->where < offset || abfd->where - offset >= maxbytes)
	{
	  bfd_set_error (bfd_error_invalid_operation);
	  return -1;
	}
      if (abfd->where - offset + size > maxbytes)
	size = maxbytes - (abfd->where - offset);
    }

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  if (abfd->last_io == bfd_io_write)
    {
      abfd->last_io = bfd_io_force;
      if (bfd_seek (abfd, 0, SEEK_CUR) != 0)
	return -1;
    }
  abfd->last_io = bfd_io_read;

  nread = abfd->iovec->bread (abfd, ptr, size);
  if (nread != -1)
    abfd->where += nread;

  return nread;
}

/*
FUNCTION
	bfd_write

SYNOPSIS
	bfd_size_type bfd_write (const void *, bfd_size_type, bfd *)
				ATTRIBUTE_WARN_UNUSED_RESULT;

DESCRIPTION
	Attempt to write SIZE bytes to ABFD's iostream from PTR.
	Return the amount written.
*/

bfd_size_type
bfd_write (const void *ptr, bfd_size_type size, bfd *abfd)
{
  file_ptr nwrote;

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    abfd = abfd->my_archive;

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  if (abfd->last_io == bfd_io_read)
    {
      abfd->last_io = bfd_io_force;
      if (bfd_seek (abfd, 0, SEEK_CUR) != 0)
	return -1;
    }
  abfd->last_io = bfd_io_write;

  nwrote = abfd->iovec->bwrite (abfd, ptr, size);
  if (nwrote != -1)
    abfd->where += nwrote;
  if ((bfd_size_type) nwrote != size)
    {
#ifdef ENOSPC
      errno = ENOSPC;
#endif
      bfd_set_error (bfd_error_system_call);
    }
  return nwrote;
}

/*
FUNCTION
	bfd_tell

SYNOPSIS
	file_ptr bfd_tell (bfd *) ATTRIBUTE_WARN_UNUSED_RESULT;

DESCRIPTION
	Return ABFD's iostream file position.
*/

file_ptr
bfd_tell (bfd *abfd)
{
  ufile_ptr offset = 0;
  file_ptr ptr;

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    {
      offset += abfd->origin;
      abfd = abfd->my_archive;
    }
  offset += abfd->origin;

  if (abfd->iovec == NULL)
    return 0;

  ptr = abfd->iovec->btell (abfd);
  abfd->where = ptr;
  return ptr - offset;
}

/*
FUNCTION
	bfd_flush

SYNOPSIS
	int bfd_flush (bfd *);

DESCRIPTION
	Flush ABFD's iostream pending IO.
*/

int
bfd_flush (bfd *abfd)
{
  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    abfd = abfd->my_archive;

  if (abfd->iovec == NULL)
    return 0;

  return abfd->iovec->bflush (abfd);
}

/*
FUNCTION
	bfd_stat

SYNOPSIS
	int bfd_stat (bfd *, struct stat *) ATTRIBUTE_WARN_UNUSED_RESULT;

DESCRIPTION
	Call fstat on ABFD's iostream.  Return 0 on success, and a
	negative value on failure.
*/

int
bfd_stat (bfd *abfd, struct stat *statbuf)
{
  int result;

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    abfd = abfd->my_archive;

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  result = abfd->iovec->bstat (abfd, statbuf);
  if (result < 0)
    bfd_set_error (bfd_error_system_call);
  return result;
}

/*
FUNCTION
	bfd_seek

SYNOPSIS
	int bfd_seek (bfd *, file_ptr, int) ATTRIBUTE_WARN_UNUSED_RESULT;

DESCRIPTION
	Call fseek on ABFD's iostream.  Return 0 on success, and a
	negative value on failure.
*/

int
bfd_seek (bfd *abfd, file_ptr position, int direction)
{
  int result;
  ufile_ptr offset = 0;

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    {
      offset += abfd->origin;
      abfd = abfd->my_archive;
    }
  offset += abfd->origin;

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  /* For the time being, a BFD may not seek to it's end.  The problem
     is that we don't easily have a way to recognize the end of an
     element in an archive.  */
  BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);

  if (direction != SEEK_CUR)
    position += offset;

  if (((direction == SEEK_CUR && position == 0)
       || (direction == SEEK_SET && (ufile_ptr) position == abfd->where))
      && abfd->last_io != bfd_io_force)
    return 0;

  abfd->last_io = bfd_io_seek;

  result = abfd->iovec->bseek (abfd, position, direction);
  if (result != 0)
    {
      /* An EINVAL error probably means that the file offset was
	 absurd.  */
      if (errno == EINVAL)
	bfd_set_error (bfd_error_file_truncated);
      else
	bfd_set_error (bfd_error_system_call);
    }
  else
    {
      /* Adjust `where' field.  */
      if (direction == SEEK_CUR)
	abfd->where += position;
      else
	abfd->where = position;
    }

  return result;
}

/*
FUNCTION
	bfd_get_mtime

SYNOPSIS
	long bfd_get_mtime (bfd *abfd);

DESCRIPTION
	Return the file modification time (as read from the file system, or
	from the archive header for archive members).

*/

long
bfd_get_mtime (bfd *abfd)
{
  struct stat buf;

  if (abfd->mtime_set)
    return abfd->mtime;

  if (bfd_stat (abfd, &buf) != 0)
    return 0;

  abfd->mtime = buf.st_mtime;		/* Save value in case anyone wants it */
  return buf.st_mtime;
}

/*
FUNCTION
	bfd_get_size

SYNOPSIS
	ufile_ptr bfd_get_size (bfd *abfd);

DESCRIPTION
	Return the file size (as read from file system) for the file
	associated with BFD @var{abfd}.

	The initial motivation for, and use of, this routine is not
	so we can get the exact size of the object the BFD applies to, since
	that might not be generally possible (archive members for example).
	It would be ideal if someone could eventually modify
	it so that such results were guaranteed.

	Instead, we want to ask questions like "is this NNN byte sized
	object I'm about to try read from file offset YYY reasonable?"
	As as example of where we might do this, some object formats
	use string tables for which the first <<sizeof (long)>> bytes of the
	table contain the size of the table itself, including the size bytes.
	If an application tries to read what it thinks is one of these
	string tables, without some way to validate the size, and for
	some reason the size is wrong (byte swapping error, wrong location
	for the string table, etc.), the only clue is likely to be a read
	error when it tries to read the table, or a "virtual memory
	exhausted" error when it tries to allocate 15 bazillon bytes
	of space for the 15 bazillon byte table it is about to read.
	This function at least allows us to answer the question, "is the
	size reasonable?".

	A return value of zero indicates the file size is unknown.
*/

ufile_ptr
bfd_get_size (bfd *abfd)
{
  /* A size of 0 means we haven't yet called bfd_stat.  A size of 1
     means we have a cached value of 0, ie. unknown.  */
  if (abfd->size <= 1 || bfd_write_p (abfd))
    {
      struct stat buf;

      if (abfd->size == 1 && !bfd_write_p (abfd))
	return 0;

      if (bfd_stat (abfd, &buf) != 0
	  || buf.st_size == 0
	  || buf.st_size - (ufile_ptr) buf.st_size != 0)
	{
	  abfd->size = 1;
	  return 0;
	}
      abfd->size = buf.st_size;
    }
  return abfd->size;
}

/*
FUNCTION
	bfd_get_file_size

SYNOPSIS
	ufile_ptr bfd_get_file_size (bfd *abfd);

DESCRIPTION
	Return the file size (as read from file system) for the file
	associated with BFD @var{abfd}.  It supports both normal files
	and archive elements.

*/

ufile_ptr
bfd_get_file_size (bfd *abfd)
{
  ufile_ptr file_size, archive_size = (ufile_ptr) -1;
  unsigned int compression_p2 = 0;

  if (abfd->my_archive != NULL
      && !bfd_is_thin_archive (abfd->my_archive))
    {
      struct areltdata *adata = (struct areltdata *) abfd->arelt_data;
      if (adata != NULL)
	{
	  archive_size = adata->parsed_size;
	  /* If the archive is compressed, assume an element won't
	     expand more than eight times file size.  */
	  if (adata->arch_header != NULL
	      && memcmp (((struct ar_hdr *) adata->arch_header)->ar_fmag,
			 "Z\012", 2) == 0)
	    compression_p2 = 3;
	  abfd = abfd->my_archive;
	}
    }

  file_size = bfd_get_size (abfd) << compression_p2;
  if (archive_size < file_size)
    return archive_size;
  return file_size;
}

/*
FUNCTION
	bfd_mmap

SYNOPSIS
	void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
			int prot, int flags, file_ptr offset,
			void **map_addr, bfd_size_type *map_len)
			ATTRIBUTE_WARN_UNUSED_RESULT;

DESCRIPTION
	Return mmap()ed region of the file, if possible and implemented.
	LEN and OFFSET do not need to be page aligned.  The page aligned
	address and length are written to MAP_ADDR and MAP_LEN.

*/

void *
bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
	  int prot, int flags, file_ptr offset,
	  void **map_addr, bfd_size_type *map_len)
{
  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    {
      offset += abfd->origin;
      abfd = abfd->my_archive;
    }
  offset += abfd->origin;

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return (void *) -1;
    }

  return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset,
			     map_addr, map_len);
}

/* Memory file I/O operations.  */

static file_ptr
memory_bread (bfd *abfd, void *ptr, file_ptr size)
{
  struct bfd_in_memory *bim;
  bfd_size_type get;

  bim = (struct bfd_in_memory *) abfd->iostream;
  get = size;
  if (abfd->where + get > bim->size)
    {
      if (bim->size < (bfd_size_type) abfd->where)
	get = 0;
      else
	get = bim->size - abfd->where;
      bfd_set_error (bfd_error_file_truncated);
    }
  memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
  return get;
}

static file_ptr
memory_bwrite (bfd *abfd, const void *ptr, file_ptr size)
{
  struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;

  if (abfd->where + size > bim->size)
    {
      bfd_size_type newsize, oldsize;

      oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
      bim->size = abfd->where + size;
      /* Round up to cut down on memory fragmentation */
      newsize = (bim->size + 127) & ~(bfd_size_type) 127;
      if (newsize > oldsize)
	{
	  bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
	  if (bim->buffer == NULL)
	    {
	      bim->size = 0;
	      return 0;
	    }
	  if (newsize > bim->size)
	    memset (bim->buffer + bim->size, 0, newsize - bim->size);
	}
    }
  memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
  return size;
}

static file_ptr
memory_btell (bfd *abfd)
{
  return abfd->where;
}

static int
memory_bseek (bfd *abfd, file_ptr position, int direction)
{
  file_ptr nwhere;
  struct bfd_in_memory *bim;

  bim = (struct bfd_in_memory *) abfd->iostream;

  if (direction == SEEK_SET)
    nwhere = position;
  else
    nwhere = abfd->where + position;

  if (nwhere < 0)
    {
      abfd->where = 0;
      errno = EINVAL;
      return -1;
    }

  if ((bfd_size_type)nwhere > bim->size)
    {
      if (abfd->direction == write_direction
	  || abfd->direction == both_direction)
	{
	  bfd_size_type newsize, oldsize;

	  oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
	  bim->size = nwhere;
	  /* Round up to cut down on memory fragmentation */
	  newsize = (bim->size + 127) & ~(bfd_size_type) 127;
	  if (newsize > oldsize)
	    {
	      bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize);
	      if (bim->buffer == NULL)
		{
		  errno = EINVAL;
		  bim->size = 0;
		  return -1;
		}
	      memset (bim->buffer + oldsize, 0, newsize - oldsize);
	    }
	}
      else
	{
	  abfd->where = bim->size;
	  errno = EINVAL;
	  bfd_set_error (bfd_error_file_truncated);
	  return -1;
	}
    }
  return 0;
}

static int
memory_bclose (struct bfd *abfd)
{
  struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;

  free (bim->buffer);
  free (bim);
  abfd->iostream = NULL;

  return 0;
}

static int
memory_bflush (bfd *abfd ATTRIBUTE_UNUSED)
{
  return 0;
}

static int
memory_bstat (bfd *abfd, struct stat *statbuf)
{
  struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream;

  memset (statbuf, 0, sizeof (*statbuf));
  statbuf->st_size = bim->size;

  return 0;
}

static void *
memory_bmmap (bfd *abfd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED,
	      bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED,
	      int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED,
	      void **map_addr ATTRIBUTE_UNUSED,
	      bfd_size_type *map_len ATTRIBUTE_UNUSED)
{
  return (void *)-1;
}

const struct bfd_iovec _bfd_memory_iovec =
{
  &memory_bread, &memory_bwrite, &memory_btell, &memory_bseek,
  &memory_bclose, &memory_bflush, &memory_bstat, &memory_bmmap
};

/*
FUNCTION
	bfd_get_current_time

SYNOPSIS
	time_t bfd_get_current_time (time_t now);

DESCRIPTION
	Returns the current time.

	If the environment variable SOURCE_DATE_EPOCH is defined
	then this is parsed and its value is returned.  Otherwise
	if the paramter NOW is non-zero, then that is returned.
	Otherwise the result of the system call "time(NULL)" is
	returned.
*/

time_t
bfd_get_current_time (time_t now)
{
  char *source_date_epoch;
  unsigned long long epoch;

  /* FIXME: We could probably cache this lookup,
     and the parsing of its value below.  */
  source_date_epoch = getenv ("SOURCE_DATE_EPOCH");

  if (source_date_epoch == NULL)
    {
      if (now)
	return now;
      return time (NULL);
    }

  epoch = strtoull (source_date_epoch, NULL, 0);

  /* If epoch == 0 then something is wrong with SOURCE_DATE_EPOCH,
     but we do not have an easy way to report it.  Since the presence
     of the environment variable implies that the user wants
     deterministic behaviour we just accept the 0 value.  */

  return (time_t) epoch;
}
