/*
  To be compatible with legacy USTAR implementations, we try fill
  the "name" fields with as much as we can, and only use the
  "prefix" field in case we need it.

  Only time we step away from this is in the case where the last
  part of the path is larger than NAME_FIELD_SIZE but all of the
  path fits into the "prefix" field. Might be that some other USTAR
  implementations can't read that, but it is within the USTAR
  standard.
*/

static union block *
write_ustar_long_name (const char *name)
{
  size_t length = strlen (name);
  union block *header;
  size_t prefix_length, name_length; /* Indicate success if one/both none zero */

  /*
    Most obvious overflow case, but note that even if we are within
    the 256 character limit, we can still fail to fit the path into
    the header
  */
  if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)
    {
      ERROR ((0, 0, _("%s: file name is too long (max %d); not dumped"),
	      quotearg_colon (name),
	      PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
      return NULL;
    }

  if (length <= NAME_FIELD_SIZE)
    {
      /*
	The most simple successful case, we would not need the "prefix" at
	all, as the complete path fits into the "name" field
      */
      prefix_length = 0;
      name_length = length;
    }
  else
    {
      /*
	We try split, placing as much as possible into the "name" field.

	We search in the last NAME_FIELD_SIZE bytes for the first slash
	and split there. We avoid searching for a slash in the first or
	last byte of the total string, as we are after a split point, not
	to confuse with a trailing or ending slash in the path.

	At this point, we now know the path is at least 101 characters.

	To make the loop clear, we actually extend the prefix part until
	we have a slash and the rest of the path fits into the "name"
	field. We start searching from the part where NAME_FIELD_SIZE is
	left.
      */
      prefix_length = length - NAME_FIELD_SIZE - 1;
      if (prefix_length == 0)
	prefix_length = 1;
      for (; prefix_length < length - 1; prefix_length++)
	if (ISSLASH (name[prefix_length]))
	  break;

      if (prefix_length != length - 1)
	{
	  /* prefix_length is set and ok, calculate the name_length */
	  name_length = length - prefix_length - 1;
	}
      else
	{
	  /*
	    We failed to find a slash to split at, no split part fits
	    into the "name" field
	  */
	  name_length = 0;
	  /*
	    But if all of the path fits into the "prefix" field, we
	    could according to the USTAR standard put it there.

	    FIXME problem is that some USTAR implementations can't
	    unpack it, so we might return an error here if
	    --format=ustar_legacy or something?
	  */
	  if (length <= PREFIX_FIELD_SIZE)
	    prefix_length = length;
	  else
	    prefix_length = 0;
	}
    }

  /*
    We signaled that failed to split by setting both lengths to zero
  */
  if ( prefix_length == 0 && name_length == 0)
    {
      ERROR ((0, 0,
	      _("%s: file name is too long (cannot be split); not dumped"),
	      quotearg_colon (name)));
      return NULL;			/* We failed fit the name into the header */
    }

  /*
    We have a header, clear the memory block and fill in the "prefix"
    and/or the "name" fields
  */
  header = find_next_block ();
  memset (header->buffer, 0, sizeof (header->buffer));

  if (prefix_length > 0)
    memcpy (header->header.prefix, name, prefix_length);
  if (name_length > 0)
    memcpy (header->header.name, name + length - name_length, name_length);

  return header;
}
